Password-protected files
This commit is contained in:
@@ -11,6 +11,7 @@ define([
|
||||
var uint8ArrayToHex = Util.uint8ArrayToHex;
|
||||
var hexToBase64 = Util.hexToBase64;
|
||||
var base64ToHex = Util.base64ToHex;
|
||||
Hash.encodeBase64 = Nacl.util.encodeBase64;
|
||||
|
||||
// This implementation must match that on the server
|
||||
// it's used for a checksum
|
||||
@@ -59,6 +60,11 @@ define([
|
||||
return '/1/' + hexToBase64(secret.channel) + '/' +
|
||||
Crypto.b64RemoveSlashes(data.fileKeyStr) + '/';
|
||||
}
|
||||
if (version === 2) {
|
||||
if (!data.fileKeyStr) { return; }
|
||||
var pass = secret.password ? 'p/' : '';
|
||||
return '/2/' + secret.type + '/' + Crypto.b64RemoveSlashes(data.fileKeyStr) + '/' + pass;
|
||||
}
|
||||
};
|
||||
|
||||
// V1
|
||||
@@ -95,12 +101,22 @@ define([
|
||||
};
|
||||
|
||||
Hash.createRandomHash = function (type, password) {
|
||||
var cryptor = Crypto.createEditCryptor2(void 0, void 0, password);
|
||||
var cryptor;
|
||||
if (type === 'file') {
|
||||
cryptor = Crypto.createFileCryptor2(void 0, password);
|
||||
return getFileHashFromKeys({
|
||||
password: Boolean(password),
|
||||
version: 2,
|
||||
type: type,
|
||||
keys: cryptor.fileKeyStr
|
||||
});
|
||||
}
|
||||
cryptor = Crypto.createEditCryptor2(void 0, void 0, password);
|
||||
return getEditHashFromKeys({
|
||||
password: Boolean(password),
|
||||
version: 2,
|
||||
type: type,
|
||||
keys: { editKeyStr: cryptor.editKeyStr }
|
||||
keys: cryptor.editKeyStr
|
||||
});
|
||||
};
|
||||
|
||||
@@ -113,6 +129,7 @@ Version 1
|
||||
|
||||
var parseTypeHash = Hash.parseTypeHash = function (type, hash) {
|
||||
if (!hash) { return; }
|
||||
var options;
|
||||
var parsed = {};
|
||||
var hashArr = fixDuplicateSlashes(hash).split('/');
|
||||
if (['media', 'file', 'user', 'invite'].indexOf(type) === -1) {
|
||||
@@ -125,7 +142,6 @@ Version 1
|
||||
parsed.version = 0;
|
||||
return parsed;
|
||||
}
|
||||
var options;
|
||||
if (hashArr[1] && hashArr[1] === '1') { // Version 1
|
||||
parsed.version = 1;
|
||||
parsed.mode = hashArr[2];
|
||||
@@ -175,6 +191,25 @@ Version 1
|
||||
parsed.key = hashArr[3].replace(/-/g, '/');
|
||||
return parsed;
|
||||
}
|
||||
if (hashArr[1] && hashArr[1] === '2') { // Version 2
|
||||
parsed.version = 2;
|
||||
parsed.app = hashArr[2];
|
||||
parsed.key = hashArr[3];
|
||||
|
||||
options = hashArr.slice(4);
|
||||
parsed.password = options.indexOf('p') !== -1;
|
||||
parsed.present = options.indexOf('present') !== -1;
|
||||
parsed.embed = options.indexOf('embed') !== -1;
|
||||
|
||||
parsed.getHash = function (opts) {
|
||||
var hash = hashArr.slice(0, 4).join('/') + '/';
|
||||
if (parsed.password) { hash += 'p/'; }
|
||||
if (opts.embed) { hash += 'embed/'; }
|
||||
if (opts.present) { hash += 'present/'; }
|
||||
return hash;
|
||||
};
|
||||
return parsed;
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
if (['user'].indexOf(type) !== -1) {
|
||||
@@ -309,11 +344,12 @@ Version 1
|
||||
}
|
||||
}
|
||||
} else if (parsed.type === "file") {
|
||||
// version 2 hashes are to be used for encrypted blobs
|
||||
secret.channel = parsed.channel;
|
||||
secret.keys = { fileKeyStr: parsed.key };
|
||||
secret.channel = base64ToHex(parsed.channel);
|
||||
secret.keys = {
|
||||
fileKeyStr: parsed.key,
|
||||
cryptKey: Nacl.util.decodeBase64(parsed.key)
|
||||
};
|
||||
} else if (parsed.type === "user") {
|
||||
// version 2 hashes are to be used for encrypted blobs
|
||||
throw new Error("User hashes can't be opened (yet)");
|
||||
}
|
||||
} else if (parsed.version === 2) {
|
||||
@@ -338,7 +374,12 @@ Version 1
|
||||
}
|
||||
}
|
||||
} else if (parsed.type === "file") {
|
||||
throw new Error("File hashes should be version 1");
|
||||
secret.channel = base64ToHex(secret.keys.chanId);
|
||||
secret.keys = Crypto.createFileCryptor2(parsed.key, password);
|
||||
secret.key = secret.keys.fileKeyStr;
|
||||
if (secret.channel.length !== 48 || secret.key.length !== 24) {
|
||||
throw new Error("The channel key and/or the encryption key is invalid");
|
||||
}
|
||||
} else if (parsed.type === "user") {
|
||||
throw new Error("User hashes can't be opened (yet)");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user