Created
July 12, 2011 03:59
-
-
Save taf2/1077369 to your computer and use it in GitHub Desktop.
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...
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* | |
* 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/'); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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...