1
0
mirror of https://github.com/moparisthebest/mail synced 2024-11-12 12:15:07 -05:00
mail/src/js/crypto/crypto.js

123 lines
3.5 KiB
JavaScript
Raw Normal View History

2013-04-02 09:02:57 -04:00
/**
* High level crypto api that invokes native crypto (if available) and
* gracefully degrades to JS crypto (if unavailable)
*/
2013-08-30 10:05:33 -04:00
define(function(require) {
'use strict';
2014-06-05 09:26:19 -04:00
var aes = require('js/crypto/aes-gcm'),
2013-08-30 10:05:33 -04:00
pbkdf2 = require('js/crypto/pbkdf2'),
config = require('js/app-config').config,
axe = require('axe');
2013-08-30 10:05:33 -04:00
2014-06-05 09:26:19 -04:00
var PBKDF2_WORKER = '/crypto/pbkdf2-worker.js';
2013-08-30 10:05:33 -04:00
2014-06-05 09:26:19 -04:00
var Crypto = function() {};
2013-09-26 07:26:57 -04:00
2013-08-30 10:05:33 -04:00
/**
2014-06-05 09:26:19 -04:00
* Encrypt plaintext using AES-GCM.
* @param {String} plaintext The input string in UTF-16
* @param {String} key The base64 encoded key
* @param {String} iv The base64 encoded IV
* @param {Function} callback(error, ciphertext)
* @return {String} The base64 encoded ciphertext
2013-08-30 10:05:33 -04:00
*/
2014-06-05 09:26:19 -04:00
Crypto.prototype.encrypt = function(plaintext, key, iv, callback) {
var ct;
2013-09-26 07:26:57 -04:00
2014-06-05 09:26:19 -04:00
try {
ct = aes.encrypt(plaintext, key, iv);
} catch (err) {
callback(err);
2013-08-30 10:05:33 -04:00
return;
}
2014-06-05 09:26:19 -04:00
callback(null, ct);
};
2013-08-30 10:05:33 -04:00
2014-06-05 09:26:19 -04:00
/**
* Decrypt ciphertext suing AES-GCM
* @param {String} ciphertext The base64 encoded ciphertext
* @param {String} key The base64 encoded key
* @param {String} iv The base64 encoded IV
* @param {Function} callback(error, plaintext)
* @return {String} The decrypted plaintext in UTF-16
*/
Crypto.prototype.decrypt = function(ciphertext, key, iv, callback) {
var pt;
2013-08-30 10:05:33 -04:00
2014-06-05 09:26:19 -04:00
try {
pt = aes.decrypt(ciphertext, key, iv);
} catch (err) {
callback(err);
return;
2013-08-30 10:05:33 -04:00
}
2014-06-05 09:26:19 -04:00
callback(null, pt);
2013-08-30 10:05:33 -04:00
};
/**
* Do PBKDF2 key derivation in a WebWorker thread
*/
Crypto.prototype.deriveKey = function(password, salt, keySize, callback) {
startWorker({
script: PBKDF2_WORKER,
args: {
password: password,
salt: salt,
keySize: keySize
},
callback: callback,
noWorker: function() {
return pbkdf2.getKey(password, salt, keySize);
}
2013-08-30 10:05:33 -04:00
});
};
//
// helper functions
//
function startWorker(options) {
2013-08-30 10:05:33 -04:00
// check for WebWorker support
if (window.Worker) {
// init webworker thread
2013-09-15 09:17:28 -04:00
var worker = new Worker(config.workerPath + options.script);
2013-08-30 10:05:33 -04:00
worker.onmessage = function(e) {
if (e.data.err) {
options.callback(e.data.err);
2013-08-30 10:05:33 -04:00
return;
}
// return result from the worker
options.callback(null, e.data);
2013-08-30 10:05:33 -04:00
};
worker.onerror = function(e) {
// show error message in logger
axe.error('Error handling web worker: Line ' + e.lineno + ' in ' + e.filename + ': ' + e.message);
// return error
options.callback({
errMsg: (e.message) ? e.message : e
});
return;
};
2013-08-30 10:05:33 -04:00
// send data to the worker
worker.postMessage(options.args);
return;
}
2013-08-30 10:05:33 -04:00
// no WebWorker support... do synchronous call
var result;
try {
result = options.noWorker();
} catch (e) {
// return error
options.callback({
errMsg: (e.message) ? e.message : e
});
return;
2013-08-30 10:05:33 -04:00
}
options.callback(null, result);
2013-08-30 10:05:33 -04:00
}
2013-09-26 07:26:57 -04:00
return Crypto;
2013-06-10 11:57:33 -04:00
});