Skip to content

Commit

Permalink
Secure workers
Browse files Browse the repository at this point in the history
This commit introduces concept of secure workers spawned only from
the code verified by the secureboot process.
Calls to `importScripts` inside worker are also restricted to scripts
boot securely.
  • Loading branch information
vibornoff committed Apr 5, 2014
1 parent 74e8700 commit 33c485c
Show file tree
Hide file tree
Showing 11 changed files with 78 additions and 185 deletions.
2 changes: 1 addition & 1 deletion decrypter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
importScripts('aesasm.js');
importScripts('js/aesasm.js');

postMessage = self.webkitPostMessage || self.postMessage;

Expand Down
2 changes: 1 addition & 1 deletion encrypter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
importScripts('aesasm.js');
importScripts('js/aesasm.js');

postMessage = self.webkitPostMessage || self.postMessage;

Expand Down
File renamed without changes.
88 changes: 0 additions & 88 deletions js/decrypter.js

This file was deleted.

2 changes: 1 addition & 1 deletion js/download2.js
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ dlQueue.getNextTask = (function() {
// }}}

if (localStorage.dl_maxSlots) {
dl_maxSlots = localStorage.dl_maxSlots;
dl_maxSlots = parseInt( localStorage.dl_maxSlots );
}

function checkLostChunks(file)
Expand Down
2 changes: 1 addition & 1 deletion js/downloader.js
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ function dl_writer(dl, is_ready) {
};
};

var Decrypter = CreateWorkers('decrypter.js?v=5', function(context, e, done) {
var Decrypter = CreateWorkers('decrypter.js', function(context, e, done) {
var dl = context[0]
, offset = context[1]

Expand Down
85 changes: 0 additions & 85 deletions js/encrypter.js

This file was deleted.

57 changes: 55 additions & 2 deletions js/functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,59 @@ function removeValue(array, value) {
array.splice($.inArray(value, array), 1);
};

/**
* Secure worker consturctor, allows to spawn new worker only from the code
* verified by secureboot process; `importScripts` calls inside worker are also
* restricted to verified scritps.
*/
function SecureWorker ( url ) {
if ( typeof url !== 'string' )
throw new TypeError();

var scode = "(function () {\n"
+ " var _scripts = " + JSON.stringify(scripts) + ";\n"
+ " var _importScripts = self.importScripts;\n"
+ " self.importScripts = function () {\n"
+ " for ( var i = 0; i < arguments.length; i++ ) {\n"
+ " var surl = _scripts[ arguments[i] ];\n"
+ " if ( typeof surl !== 'string' ) throw new Error();\n"
+ " arguments[i] = surl;\n"
+ " }\n"
+ " _importScripts.apply( self, arguments );\n"
+ " };\n"
+ "})();\n"
+ "importScripts('"+url+"')"

var sblob;
if ( typeof BlobBuilder === 'function' ) {
var bb = new BlobBuilder();
bb.append(scode);
sblob = bb.getBlob('text/javascript');
}
else {
sblob = new Blob( [ scode ], { type: "text/javascript" } );
}

var surl = window.URL.createObjectURL(sblob);

var thiz = this;
var sworker = new Worker(surl);

sworker.onmessage = function ( e ) {
(thiz.onmessage||function(){}).call( thiz, e );
}

thiz.postMessage = function () {
sworker.postMessage.apply( sworker, arguments );
};

thiz.terminate = function () {
sworker.terminate();
window.URL.revokeObjectURL(surl);
sworker = null;
};
}

/**
* Create a pool of workers, it returns a Queue object
* so it can be called many times and it'd be throttled
Expand All @@ -625,7 +678,7 @@ function CreateWorkers(url, message, size) {
}

function create(i) {
var w = new Worker(url);
var w = new SecureWorker(url);
w.id = i;
w.busy = false;
w.postMessage = w.webkitPostMessage || w.postMessage;
Expand All @@ -647,7 +700,7 @@ function CreateWorkers(url, message, size) {
$.each(task, function(e, t) {
if (e == 0) {
worker[i].context = t;
} else if (t.constructor == 'Uint8Array' && typeof MSBlobBuilder !== "function") {
} else if (t.constructor === Uint8Array && typeof MSBlobBuilder !== "function") {
worker[i].postMessage(t.buffer,[t.buffer]);
} else {
worker[i].postMessage(t);
Expand Down
2 changes: 1 addition & 1 deletion js/upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ function ul_dispatch_encryption()

if (typeof(ul_workers[id]) != "object")
{
ul_workers[id] = new Worker('encrypter.js');
ul_workers[id] = new SecureWorker('encrypter.js');
ul_workers[id].postMessage = ul_workers[id].webkitPostMessage || ul_workers[id].postMessage;

ul_workers[id].onmessage = function(e)
Expand Down
4 changes: 2 additions & 2 deletions js/upload2.js
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,7 @@ function worker_uploader(task) {
}

var ul_queue = new UploadQueue
, ul_maxSlots = 4
, ul_maxSlots = localStorage.ul_maxSlots ? parseInt( localStorage.ul_maxSlots ) : 4
, Encrypter
, ulQueue = new QueueClass(worker_uploader, ul_maxSlots)
, ul_skipIdentical = 0
Expand All @@ -608,7 +608,7 @@ Encrypter = CreateWorkers('encrypter.js', function(context, e, done) {
chunk.suffix = '/' + start + '?c=' + base64urlencode(chksum(chunk.bytes.buffer));
done();
}
}, 4);
}, ul_maxSlots );

function resetUploadDownload() {
var ul_len = 0, dl_len = 0;
Expand Down
19 changes: 16 additions & 3 deletions secureboot.js
Original file line number Diff line number Diff line change
Expand Up @@ -321,11 +321,12 @@ else
var jsl = []

jsl.push({f:'lang/' + lang + langv + '.json', n: 'lang', j:3});
jsl.push({f:'sjcl.js', n: 'sjcl_js', j:1}); // Will be replaced with asmCrypto soon
jsl.push({f:'js/asmcrypto.js',n:'asmcrypto_js',j:1});
jsl.push({f:'js/crypto.js', n: 'crypto_js', j:1,w:5});
jsl.push({f:'js/user.js', n: 'user_js', j:1});
jsl.push({f:'js/hex.js', n: 'hex_js', j:1});
jsl.push({f:'js/functions.js', n: 'functions_js', j:1});
jsl.push({f:'sjcl.js', n: 'sjcl_js', j:1});
jsl.push({f:'js/rsa.js', n: 'rsa_js', j:1});
jsl.push({f:'js/keygen.js', n: 'keygen_js', j:1});
jsl.push({f:'js/mouse.js', n: 'mouse_js', j:1});
Expand Down Expand Up @@ -378,7 +379,12 @@ else
jsl.push({f:'js/checkboxes.js', n: 'checkboxes_js', j:1});
jsl.push({f:'js/Int64.js', n: 'int64_js', j:1});
jsl.push({f:'js/zip64.js', n: 'zip_js', j:1});
jsl.push({f:'js/asmcrypto.js',n:'asmcrypto_js',j:1});
/* SecureWorker stuff {{{ */
jsl.push({f:'js/aesasm.js',n:'aesasm_js',j:4}); // Will be replaced with asmCrypto soon
jsl.push({f:'js/asmcrypto.js',n:'asmcrypto_js',j:4});
jsl.push({f:'encrypter.js',n:'encrypter_js',j:4});
jsl.push({f:'decrypter.js',n:'decrypter_js',j:4});
/* }}} */
var jsl2 =
{
'about': {f:'html/about.html', n: 'about', j:0},
Expand Down Expand Up @@ -533,7 +539,7 @@ else
i++;
}
}
var pages = [];
var pages = [], scripts = {};
function getxhr()
{
return (typeof XDomainRequest != 'undefined' && typeof ArrayBuffer == 'undefined') ? new XDomainRequest() : new XMLHttpRequest();
Expand Down Expand Up @@ -746,20 +752,27 @@ else
}
}
else if (jsl[i].j == 3) l = JSON.parse(jsl[i].text);
else if (jsl[i].j == 4) scripts[jsl[i].f] = jsl[i].text;
else if (jsl[i].j == 0) pages[jsl[i].n] = jsl[i].text;
}
if (window.URL)
{
try
{
var blob = new Blob(cssar, { type: "text/css" });
for ( var f in scripts ) scripts[f] = window.URL.createObjectURL( new Blob( [ scripts[f] ], { type: 'text/javascript' } ) );
}
catch(e)
{
window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder;
var bb = new BlobBuilder();
for (var i in cssar) bb.append(cssar[i]);
var blob = bb.getBlob('text/css');
for ( var f in scripts ) {
bb = new BlobBuilder();
bb.append( scripts[f] );
scripts[f] = window.URL.createObjectURL( bb.getBlob('text/javascript') );
}
}
var link = document.createElement('link');
link.setAttribute('rel', 'stylesheet');
Expand Down

0 comments on commit 33c485c

Please sign in to comment.