2013-11-29 20:39:42 +00:00
|
|
|
define(function(require) {
|
|
|
|
var FILE_SYSTEM_NAME = require('src/constants').FILE_SYSTEM_NAME;
|
|
|
|
|
|
|
|
// AES encryption, see http://code.google.com/p/crypto-js/#AES
|
|
|
|
require("crypto-js/rollups/aes");
|
|
|
|
// DES, Triple DES, see http://code.google.com/p/crypto-js/#DES,_Triple_DES
|
|
|
|
require("crypto-js/rollups/tripledes");
|
|
|
|
// Rabbit, see http://code.google.com/p/crypto-js/#Rabbi
|
|
|
|
require("crypto-js/rollups/rabbit");
|
|
|
|
|
|
|
|
function CryptoWrappedContext(context, encrypt, decrypt) {
|
|
|
|
this.context = context;
|
|
|
|
this.encrypt = encrypt;
|
|
|
|
this.decrypt = decrypt;
|
|
|
|
}
|
|
|
|
CryptoWrappedContext.prototype.clear = function(callback) {
|
|
|
|
this.context.clear(callback);
|
|
|
|
};
|
|
|
|
CryptoWrappedContext.prototype.get = function(key, callback) {
|
|
|
|
var that = this;
|
2013-11-29 21:00:41 +00:00
|
|
|
this.context.get(key, function(err, value) {
|
2013-11-29 20:39:42 +00:00
|
|
|
if(err) {
|
|
|
|
callback(err);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if(value) {
|
|
|
|
value = that.decrypt(value);
|
|
|
|
}
|
|
|
|
callback(null, value);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
CryptoWrappedContext.prototype.put = function(key, value, callback) {
|
|
|
|
var encryptedValue = this.encrypt(value);
|
2013-11-29 21:00:41 +00:00
|
|
|
this.context.put(key, encryptedValue, callback);
|
2013-11-29 20:39:42 +00:00
|
|
|
};
|
|
|
|
CryptoWrappedContext.prototype.delete = function(key, callback) {
|
2013-11-29 21:00:41 +00:00
|
|
|
this.context.delete(key, callback);
|
2013-11-29 20:39:42 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// Custom formatting for encryption objects <-> strings
|
|
|
|
var formatter = {
|
|
|
|
stringify: function(cipherParams) {
|
|
|
|
// create json object with ciphertext
|
|
|
|
var jsonObj = {
|
|
|
|
ct: cipherParams.ciphertext.toString(CryptoJS.enc.Base64)
|
|
|
|
};
|
|
|
|
|
|
|
|
// cache iv and salt
|
|
|
|
if (cipherParams.iv) {
|
|
|
|
jsonObj.iv = cipherParams.iv.toString();
|
|
|
|
}
|
|
|
|
if (cipherParams.salt) {
|
|
|
|
jsonObj.s = cipherParams.salt.toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
// stringify json object
|
|
|
|
return JSON.stringify(jsonObj);
|
|
|
|
},
|
|
|
|
|
|
|
|
parse: function(jsonString) {
|
|
|
|
// parse json string
|
|
|
|
var jsonObj;
|
|
|
|
try {
|
|
|
|
jsonObj = JSON.parse(jsonString);
|
|
|
|
} catch(e) {
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
|
|
|
|
// extract ciphertext from json object, and create cipher params object
|
|
|
|
var cipherParams = CryptoJS.lib.CipherParams.create({
|
|
|
|
ciphertext: CryptoJS.enc.Base64.parse(jsonObj.ct)
|
|
|
|
});
|
|
|
|
|
|
|
|
// extract iv and salt
|
|
|
|
if (jsonObj.iv) {
|
|
|
|
cipherParams.iv = CryptoJS.enc.Hex.parse(jsonObj.iv);
|
|
|
|
}
|
|
|
|
if (jsonObj.s) {
|
|
|
|
cipherParams.salt = CryptoJS.enc.Hex.parse(jsonObj.s);
|
|
|
|
}
|
|
|
|
|
|
|
|
return cipherParams;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
function buildCryptoWrapper(encryptionType) {
|
|
|
|
// It is up to the app using this wrapper how the passphrase is acquired, probably by
|
|
|
|
// prompting the user to enter it when the file system is being opened.
|
|
|
|
function CryptoWrappedProvider(passphrase, provider) {
|
|
|
|
this.provider = provider;
|
|
|
|
this.encrypt = function(plain) {
|
|
|
|
console.log('encrypt', plain, CryptoJS[encryptionType].encrypt(plain, passphrase).toString());
|
|
|
|
return CryptoJS[encryptionType].encrypt(plain, passphrase, {format: formatter}).toString();
|
|
|
|
};
|
|
|
|
this.decrypt = function(encrypted) {
|
|
|
|
console.log('decrypt', encrypted, CryptoJS[encryptionType].decrypt(encrypted, passphrase).toString());
|
|
|
|
return CryptoJS[encryptionType].decrypt(encrypted, passphrase, {format: formatter}).toString();
|
|
|
|
};
|
|
|
|
}
|
|
|
|
CryptoWrappedProvider.isSupported = function() {
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
|
|
|
CryptoWrappedProvider.prototype.open = function(callback) {
|
|
|
|
this.provider.open(callback);
|
|
|
|
};
|
|
|
|
CryptoWrappedProvider.prototype.getReadOnlyContext = function() {
|
|
|
|
return new CryptoWrappedContext(this.provider.getReadOnlyContext(), this.encrypt, this.decrypt);
|
|
|
|
};
|
|
|
|
CryptoWrappedProvider.prototype.getReadWriteContext = function() {
|
|
|
|
return new CryptoWrappedContext(this.provider.getReadWriteContext(), this.encrypt, this.decrypt);
|
|
|
|
};
|
|
|
|
|
|
|
|
return CryptoWrappedProvider;
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
AESWrapper: buildCryptoWrapper('AES'),
|
|
|
|
TripleDESWrapper: buildCryptoWrapper('TripleDES'),
|
|
|
|
RabbitWrapper: buildCryptoWrapper('Rabbit')
|
|
|
|
};
|
|
|
|
});
|