prepare for upload

This commit is contained in:
ansuz
2017-04-28 11:45:53 +02:00
parent e2942f959b
commit e132ccf94a
4 changed files with 236 additions and 56 deletions

View File

@@ -2,39 +2,75 @@ define([
'/bower_components/tweetnacl/nacl-fast.min.js',
], function () {
var Nacl = window.nacl;
var PARANOIA = true;
var chunkLength = 131088;
var plainChunkLength = 128 * 1024;
var cypherChunkLength = 131088;
var slice = function (A) {
return Array.prototype.slice.call(A);
};
var createNonce = function () {
return new Uint8Array(new Array(24).fill(0));
};
var increment = function (N) {
var l = N.length;
while (l-- > 1) {
if (N[l] !== 255) { return void N[l]++; }
if (PARANOIA) {
if (typeof(N[l]) !== 'number') {
throw new Error('E_UNSAFE_TYPE');
}
if (N[l] > 255) {
throw new Error('E_OUT_OF_BOUNDS');
}
}
/* jshint probably suspects this is unsafe because we lack types
but as long as this is only used on nonces, it should be safe */
if (N[l] !== 255) { return void N[l]++; } // jshint ignore:line
N[l] = 0;
// you don't need to worry about this running out.
// you'd need a REAAAALLY big file
if (l === 0) { return true; }
}
};
var joinChunks = function (B) {
var joinChunks = function (chunks) {
return new Uint8Array(chunks.reduce(function (A, B) {
return slice(A).concat(slice(B));
}, []));
};
var padChunk = function (A) {
var padding;
if (A.length === plainChunkLength) { return A; }
if (A.length < plainChunkLength) {
padding = new Array(plainChunkLength - A.length).fill(32);
return A.concat(padding);
}
if (A.length > plainChunkLength) {
// how many times larger is it?
var chunks = Math.ceil(A.length / plainChunkLength);
padding = new Array((plainChunkLength * chunks) - A.length).fill(32);
return A.concat(padding);
}
};
var decrypt = function (u8, key, cb) {
var nonce = new Uint8Array(new Array(24).fill(0));
var nonce = createNonce();
var i = 0;
var takeChunk = function () {
let start = i * chunkLength;
let end = start + chunkLength;
var start = i * cypherChunkLength;
var end = start + cypherChunkLength;
i++;
let box = new Uint8Array(u8.subarray(start, end));
var box = new Uint8Array(u8.subarray(start, end));
// decrypt the chunk
let plaintext = Nacl.secretbox.open(box, nonce, key);
var plaintext = Nacl.secretbox.open(box, nonce, key);
// TODO handle nonce-too-large-error
increment(nonce);
return plaintext;
};
@@ -46,8 +82,9 @@ define([
};
// decrypt metadata
for (; !res.metadata && i * chunkLength < u8.length;) {
var chunk = takeChunk();
var chunk;
for (; !res.metadata && i * cypherChunkLength < u8.length;) {
chunk = takeChunk();
buffer += Nacl.util.encodeUTF8(chunk);
try {
res.metadata = JSON.parse(buffer);
@@ -63,15 +100,16 @@ define([
});
}
var fail = function () {
cb("DECRYPTION_ERROR");
};
var chunks = [];
// decrypt file contents
for (;i * chunkLength < u8.length;) {
let chunk = takeChunk();
for (;i * cypherChunkLength < u8.length;) {
chunk = takeChunk();
if (!chunk) {
return void window.setTimeout(function () {
cb('DECRYPTION_ERROR');
});
//throw new Error('failed to parse');
return window.setTimeout(fail);
}
chunks.push(chunk);
}
@@ -82,7 +120,63 @@ define([
cb(void 0, res);
};
// metadata
/* { filename: 'raccoon.jpg', type: 'image/jpeg' } */
/* TODO
in your callback, return an object which you can iterate...
*/
var encrypt = function (u8, metadata, key, cb) {
var nonce = createNonce();
// encode metadata
var metaBuffer = Array.prototype.slice
.call(Nacl.util.decodeUTF8(JSON.stringify(metadata)));
var plaintext = new Uint8Array(padChunk(metaBuffer));
var chunks = [];
var j = 0;
var start;
var end;
var part;
var box;
// prepend some metadata
for (;j * plainChunkLength < plaintext.length; j++) {
start = j * plainChunkLength;
end = start + plainChunkLength;
part = plaintext.subarray(start, end);
box = Nacl.secretbox(part, nonce, key);
chunks.push(box);
increment(nonce);
}
// append the encrypted file chunks
var i = 0;
for (;i * plainChunkLength < u8.length; i++) {
start = i * plainChunkLength;
end = start + plainChunkLength;
part = new Uint8Array(u8.subarray(start, end));
box = Nacl.secretbox(part, nonce, key);
chunks.push(box);
increment(nonce);
}
// TODO do something with the chunks...
};
return {
decrypt: decrypt,
encrypt: encrypt,
};
});