Create a gist now
Instantly share code, notes, and snippets.
A node.js proxy for decrypting encrypted files on the fly by first requesting authorization and then using the retrieved decryption key to decode a remote file while serving it to the client...
/*
*
* Streaming server to decrypt recorded calls on the fly.
*
* To start a user sends an HTTPS encrypted request with their decryption password
*
* We send a init request to the rails application asking it to send us the decryption keys for the specific requested call
*
*/
var http = require('http'),
querystring = require('querystring'),
crypto = require('crypto'),
base64 = require('base64'),
URL = require('url'),
config = require(__dirname + '/config')[(process.env.NODE_ENV || 'development')];
// setup the forward request options
var AccessOptions = {
host: config.host,
port: config.port,
path: function(callid, passtoken) { return '/calls/secure_access' }
}
var app = http.createServer(function (req, res) {
var params = querystring.parse(req.url.split('?')[1]);
var format = params.format == 'wav' ? 'audio/wav' : 'audio/mp3';
// send access request
var opts = {host: AccessOptions.host, port: AccessOptions.port, path: AccessOptions.path(params.cid, params.token)};
http.get(opts, function(response) {
var messageBuffer = new Buffer(128); // smallish for testing
var bufferSize = 0;
response.on('data', function(chunk) {
if ((bufferSize + chunk.length) > messageBuffer.length) {
var biggerBuffer = new Buffer( (bufferSize+chunk.length) * 2 );
messageBuffer.copy(biggerBuffer);
delete messageBuffer;
messageBuffer = biggerBuffer;
}
chunk.copy(messageBuffer, bufferSize);
bufferSize += chunk.length;
});
response.on('end', function() {
//console.log(messageBuffer.toString('utf8', 0, bufferSize));
var message = JSON.parse(messageBuffer.toString('utf8', 0, bufferSize));
var decipher = crypto.createDecipheriv('aes-256-cbc', base64.decode(message.key), base64.decode(message.iv));
var uri = URL.parse(message.audio_url);
var opts = {host: uri.hostname, port: uri.port, path: uri.pathname};
var request = http.get(opts, function(response) {
res.writeHead(200, {'Content-Type': format});
response.on('data', function(chunk) {
res.write(decipher.update(chunk, 'binary', 'binary'), 'binary');
});
response.on('end', function() {
res.end(decipher.final('binary'), 'binary');
});
});
});
});
});
module.exports = exports = app;
if (!module.parent) {
app.listen(1337, "127.0.0.1");
process.on('SIGINT', process.exit.bind(process));
console.log('Server running at http://127.0.0.1:1337/');
}

@taf2

Owner

taf2 commented on 12 Jul 2011

The goliath version is less complete and has a dependency on base64 encoding in away i believe is unnecessary, but haven't explored in more detail...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment