mirror of
https://github.com/moparisthebest/mail
synced 2024-11-22 08:52:15 -05:00
refactoring of crypto worker code and lots of cleanup
This commit is contained in:
parent
622e787ba7
commit
f2a14ad65b
@ -4,7 +4,6 @@
|
||||
"jquery": true,
|
||||
"node": true,
|
||||
"browser": true,
|
||||
"camelcase": true,
|
||||
"nonew": true,
|
||||
"curly": true,
|
||||
"eqeqeq": true,
|
||||
@ -32,10 +31,12 @@
|
||||
"describe",
|
||||
"it",
|
||||
"chai",
|
||||
"asyncTest",
|
||||
"ok",
|
||||
"equal",
|
||||
"deepEqual",
|
||||
"start",
|
||||
"TestData",
|
||||
"chrome"
|
||||
],
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
var CryptoBatch = function(aes, rsa, util, _) {
|
||||
|
||||
/**
|
||||
* Encrypt and sign a an item using AES and RSA
|
||||
* Encrypt and sign an item using AES and RSA
|
||||
* @param i [Object] The item to encrypt
|
||||
* @param receiverPubkey [String] The public key used to encrypt
|
||||
* @param senderKeyId [String] The sender's private key ID used to sign
|
||||
|
@ -29,7 +29,11 @@ app.crypto.Crypto = function(window, util) {
|
||||
self.rsaKeySize = args.rsaKeySize;
|
||||
|
||||
// derive PBKDF2 from password in web worker thread
|
||||
self.deriveKey(args.password, self.keySize, function(pbkdf2) {
|
||||
self.deriveKey(args.password, self.keySize, function(err, pbkdf2) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// check if key exists
|
||||
if (!args.storedKeypair) {
|
||||
@ -106,29 +110,13 @@ app.crypto.Crypto = function(window, util) {
|
||||
* Do PBKDF2 key derivation in a WebWorker thread
|
||||
*/
|
||||
this.deriveKey = function(password, keySize, callback) {
|
||||
// check for WebWorker support
|
||||
if (window.Worker) {
|
||||
|
||||
// init webworker thread
|
||||
var worker = new Worker(app.config.workerPath + '/crypto/pbkdf2-worker.js');
|
||||
|
||||
worker.onmessage = function(e) {
|
||||
// return derived key from the worker
|
||||
callback(e.data);
|
||||
};
|
||||
|
||||
// send plaintext data to the worker
|
||||
worker.postMessage({
|
||||
password: password,
|
||||
keySize: keySize
|
||||
});
|
||||
|
||||
} else {
|
||||
// no WebWorker support... do synchronous call
|
||||
startWorker('/crypto/pbkdf2-worker.js', {
|
||||
password: password,
|
||||
keySize: keySize
|
||||
}, callback, function() {
|
||||
var pbkdf2 = new app.crypto.PBKDF2();
|
||||
var key = pbkdf2.getKey(password, keySize);
|
||||
callback(key);
|
||||
}
|
||||
return pbkdf2.getKey(password, keySize);
|
||||
});
|
||||
};
|
||||
|
||||
//
|
||||
@ -136,43 +124,29 @@ app.crypto.Crypto = function(window, util) {
|
||||
//
|
||||
|
||||
this.aesEncrypt = function(plaintext, key, iv, callback) {
|
||||
if (window.Worker) {
|
||||
var self = this;
|
||||
|
||||
var worker = new Worker(app.config.workerPath + '/crypto/aes-worker.js');
|
||||
worker.onmessage = function(e) {
|
||||
callback(e.data);
|
||||
};
|
||||
worker.postMessage({
|
||||
type: 'encrypt',
|
||||
plaintext: plaintext,
|
||||
key: key,
|
||||
iv: iv
|
||||
});
|
||||
|
||||
} else {
|
||||
var ct = this.aesEncryptSync(plaintext, key, iv);
|
||||
callback(ct);
|
||||
}
|
||||
startWorker('/crypto/aes-worker.js', {
|
||||
type: 'encrypt',
|
||||
plaintext: plaintext,
|
||||
key: key,
|
||||
iv: iv
|
||||
}, callback, function() {
|
||||
return self.aesEncryptSync(plaintext, key, iv);
|
||||
});
|
||||
};
|
||||
|
||||
this.aesDecrypt = function(ciphertext, key, iv, callback) {
|
||||
if (window.Worker) {
|
||||
var self = this;
|
||||
|
||||
var worker = new Worker(app.config.workerPath + '/crypto/aes-worker.js');
|
||||
worker.onmessage = function(e) {
|
||||
callback(e.data);
|
||||
};
|
||||
worker.postMessage({
|
||||
type: 'decrypt',
|
||||
ciphertext: ciphertext,
|
||||
key: key,
|
||||
iv: iv
|
||||
});
|
||||
|
||||
} else {
|
||||
var pt = this.aesDecryptSync(ciphertext, key, iv);
|
||||
callback(pt);
|
||||
}
|
||||
startWorker('/crypto/aes-worker.js', {
|
||||
type: 'decrypt',
|
||||
ciphertext: ciphertext,
|
||||
key: key,
|
||||
iv: iv
|
||||
}, callback, function() {
|
||||
return self.aesDecryptSync(ciphertext, key, iv);
|
||||
});
|
||||
};
|
||||
|
||||
this.aesEncryptSync = function(plaintext, key, iv) {
|
||||
@ -188,41 +162,23 @@ app.crypto.Crypto = function(window, util) {
|
||||
//
|
||||
|
||||
this.aesEncryptList = function(list, callback) {
|
||||
if (window.Worker) {
|
||||
|
||||
var worker = new Worker(app.config.workerPath + '/crypto/aes-batch-worker.js');
|
||||
worker.onmessage = function(e) {
|
||||
callback(e.data);
|
||||
};
|
||||
worker.postMessage({
|
||||
type: 'encrypt',
|
||||
list: list
|
||||
});
|
||||
|
||||
} else {
|
||||
startWorker('/crypto/aes-batch-worker.js', {
|
||||
type: 'encrypt',
|
||||
list: list
|
||||
}, callback, function() {
|
||||
var batch = new cryptoLib.CryptoBatch(aes);
|
||||
var encryptedList = batch.encryptList(list);
|
||||
callback(encryptedList);
|
||||
}
|
||||
return batch.encryptList(list);
|
||||
});
|
||||
};
|
||||
|
||||
this.aesDecryptList = function(list, callback) {
|
||||
if (window.Worker) {
|
||||
|
||||
var worker = new Worker(app.config.workerPath + '/crypto/aes-batch-worker.js');
|
||||
worker.onmessage = function(e) {
|
||||
callback(e.data);
|
||||
};
|
||||
worker.postMessage({
|
||||
type: 'decrypt',
|
||||
list: list
|
||||
});
|
||||
|
||||
} else {
|
||||
startWorker('/crypto/aes-batch-worker.js', {
|
||||
type: 'decrypt',
|
||||
list: list
|
||||
}, callback, function() {
|
||||
var batch = new cryptoLib.CryptoBatch(aes);
|
||||
var decryptedList = batch.decryptList(list);
|
||||
callback(decryptedList);
|
||||
}
|
||||
return batch.decryptList(list);
|
||||
});
|
||||
};
|
||||
|
||||
//
|
||||
@ -258,24 +214,15 @@ app.crypto.Crypto = function(window, util) {
|
||||
envelopes.push(envelope);
|
||||
});
|
||||
|
||||
if (window.Worker) {
|
||||
|
||||
var worker = new Worker(app.config.workerPath + '/crypto/crypto-batch-worker.js');
|
||||
worker.onmessage = function(e) {
|
||||
callback(null, e.data);
|
||||
};
|
||||
worker.postMessage({
|
||||
type: 'encrypt',
|
||||
list: envelopes,
|
||||
senderPrivkey: senderPrivkey,
|
||||
receiverPubkeys: receiverPubkeys
|
||||
});
|
||||
|
||||
} else {
|
||||
startWorker('/crypto/crypto-batch-worker.js', {
|
||||
type: 'encrypt',
|
||||
list: envelopes,
|
||||
senderPrivkey: senderPrivkey,
|
||||
receiverPubkeys: receiverPubkeys
|
||||
}, callback, function() {
|
||||
var batch = new cryptoLib.CryptoBatch(aes, rsa, util, _);
|
||||
var encryptedList = batch.encryptListForUser(envelopes, receiverPubkeys, senderPrivkey);
|
||||
callback(null, encryptedList);
|
||||
}
|
||||
return batch.encryptListForUser(envelopes, receiverPubkeys, senderPrivkey);
|
||||
});
|
||||
};
|
||||
|
||||
this.decryptListForUser = function(list, senderPubkeys, callback) {
|
||||
@ -292,24 +239,37 @@ app.crypto.Crypto = function(window, util) {
|
||||
privateKey: keypair.privkeyPem
|
||||
};
|
||||
|
||||
if (window.Worker) {
|
||||
|
||||
var worker = new Worker(app.config.workerPath + '/crypto/crypto-batch-worker.js');
|
||||
worker.onmessage = function(e) {
|
||||
callback(null, e.data);
|
||||
};
|
||||
worker.postMessage({
|
||||
type: 'decrypt',
|
||||
list: list,
|
||||
receiverPrivkey: receiverPrivkey,
|
||||
senderPubkeys: senderPubkeys
|
||||
});
|
||||
|
||||
} else {
|
||||
startWorker('/crypto/crypto-batch-worker.js', {
|
||||
type: 'decrypt',
|
||||
list: list,
|
||||
receiverPrivkey: receiverPrivkey,
|
||||
senderPubkeys: senderPubkeys
|
||||
}, callback, function() {
|
||||
var batch = new cryptoLib.CryptoBatch(aes, rsa, util, _);
|
||||
var decryptedList = batch.decryptListForUser(list, senderPubkeys, receiverPrivkey);
|
||||
callback(null, decryptedList);
|
||||
}
|
||||
return batch.decryptListForUser(list, senderPubkeys, receiverPrivkey);
|
||||
});
|
||||
};
|
||||
|
||||
function startWorker(script, args, callback, noWorker) {
|
||||
// check for WebWorker support
|
||||
if (window.Worker) {
|
||||
|
||||
// init webworker thread
|
||||
var worker = new Worker(app.config.workerPath + script);
|
||||
|
||||
worker.onmessage = function(e) {
|
||||
// return derived key from the worker
|
||||
callback(null, e.data);
|
||||
};
|
||||
|
||||
// send data to the worker
|
||||
worker.postMessage(args);
|
||||
|
||||
} else {
|
||||
// no WebWorker support... do synchronous call
|
||||
var result = noWorker();
|
||||
callback(null, result);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
@ -1,341 +0,0 @@
|
||||
/**
|
||||
* A wrapper for asymmetric OpenPGP encryption logic
|
||||
*/
|
||||
app.crypto.PGP = function(window, openpgp, util, server) {
|
||||
'use strict';
|
||||
|
||||
var self = this,
|
||||
privateKey, // user's private key
|
||||
publicKey, // user's public key
|
||||
passphrase; // user's passphrase used for decryption
|
||||
|
||||
openpgp.init(); // initialize OpenPGP.js
|
||||
|
||||
//
|
||||
// Key management
|
||||
//
|
||||
|
||||
/**
|
||||
* Check if user already has a public key on the server and if not,
|
||||
* generate a new keypait for the user
|
||||
*/
|
||||
self.initKeyPair = function(loginInfo, callback, displayCallback, finishCallback) {
|
||||
// check if user already has a keypair in local storage
|
||||
if (loginInfo.publicKeyId) {
|
||||
// decode base 64 key ID
|
||||
var keyId = window.atob(loginInfo.publicKeyId);
|
||||
// read the user's keys from local storage
|
||||
callback(keyId);
|
||||
|
||||
} else {
|
||||
// user has no key pair yet
|
||||
displayCallback(function() {
|
||||
// generate new key pair with 2048 bit RSA keys
|
||||
var keys = self.generateKeys(2048);
|
||||
var keyId = keys.privateKey.getKeyId();
|
||||
|
||||
// display finish
|
||||
finishCallback(keyId);
|
||||
// read the user's keys from local storage
|
||||
callback(keyId);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a key pair for the user
|
||||
* @param numBits [int] number of bits for the key creation. (should be 1024+, generally)
|
||||
* @email [string] user's email address
|
||||
* @pass [string] a passphrase used to protect the private key
|
||||
*/
|
||||
self.generateKeys = function(numBits) {
|
||||
// check passphrase
|
||||
if (!passphrase && passphrase !== '') {
|
||||
throw 'No passphrase set!';
|
||||
}
|
||||
|
||||
var userId = 'SafeWith.me User <anonymous@dunno.com>';
|
||||
var keys = openpgp.generate_key_pair(1, numBits, userId, passphrase); // keytype 1=RSA
|
||||
|
||||
self.importKeys(keys.publicKeyArmored, keys.privateKeyArmored);
|
||||
|
||||
return keys;
|
||||
};
|
||||
|
||||
/**
|
||||
* Import the users key into the HTML5 local storage
|
||||
*/
|
||||
self.importKeys = function(publicKeyArmored, privateKeyArmored) {
|
||||
// check passphrase
|
||||
if (!passphrase && passphrase !== '') {
|
||||
throw 'No passphrase set!';
|
||||
}
|
||||
|
||||
// store keys in html5 local storage
|
||||
openpgp.keyring.importPrivateKey(privateKeyArmored, passphrase);
|
||||
openpgp.keyring.importPublicKey(publicKeyArmored);
|
||||
openpgp.keyring.store();
|
||||
};
|
||||
|
||||
/**
|
||||
* Export the keys by using the HTML5 FileWriter
|
||||
*/
|
||||
self.exportKeys = function(callback) {
|
||||
// build blob
|
||||
var buf = util.binStr2ArrBuf(publicKey.armored + privateKey.armored);
|
||||
var blob = util.arrBuf2Blob(buf, 'text/plain');
|
||||
// create url
|
||||
util.createUrl(undefined, blob, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Read the users keys from the browser's HTML5 local storage
|
||||
* @email [string] user's email address
|
||||
* @keyId [string] the public key ID in unicode (not base 64)
|
||||
*/
|
||||
self.readKeys = function(keyId, callback, errorCallback) {
|
||||
// read keys from keyring (local storage)
|
||||
var privKeyQuery = openpgp.keyring.getPrivateKeyForKeyId(keyId)[0];
|
||||
if (privKeyQuery) {
|
||||
privateKey = privKeyQuery.key;
|
||||
}
|
||||
publicKey = openpgp.keyring.getPublicKeysForKeyId(keyId)[0];
|
||||
|
||||
// check keys
|
||||
if (!publicKey || !privateKey || (publicKey.keyId !== privateKey.keyId)) {
|
||||
// no amtching keys found in the key store
|
||||
return false;
|
||||
}
|
||||
|
||||
// read passphrase from local storage if no passphrase is specified
|
||||
if (!passphrase && passphrase !== '') {
|
||||
passphrase = window.sessionStorage.getItem(window.btoa(keyId) + 'Passphrase');
|
||||
}
|
||||
|
||||
// check passphrase
|
||||
if (!passphrase && passphrase !== '') {
|
||||
return false;
|
||||
}
|
||||
// do test encrypt/decrypt to verify passphrase
|
||||
try {
|
||||
var testCt = self.asymmetricEncrypt('test');
|
||||
self.asymmetricDecrypt(testCt);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a new key pair for the user and persist the public key on the server
|
||||
*/
|
||||
self.syncKeysToServer = function(email, callback) {
|
||||
// base64 encode key ID
|
||||
var keyId = publicKey.keyId;
|
||||
var encodedKeyId = window.btoa(keyId);
|
||||
var pubKey = {
|
||||
keyId: encodedKeyId,
|
||||
ownerEmail: email,
|
||||
asciiArmored: publicKey.armored
|
||||
};
|
||||
var privKey = {
|
||||
keyId: encodedKeyId,
|
||||
ownerEmail: email,
|
||||
asciiArmored: privateKey.armored
|
||||
};
|
||||
|
||||
var jsonPublicKey = JSON.stringify(pubKey);
|
||||
var jsonPrivateKey = JSON.stringify(privKey);
|
||||
|
||||
// first upload public key
|
||||
server.xhr({
|
||||
type: 'POST',
|
||||
uri: '/ws/publicKeys',
|
||||
contentType: 'application/json',
|
||||
expected: 201,
|
||||
body: jsonPublicKey,
|
||||
success: function(resp) {
|
||||
uploadPrivateKeys();
|
||||
},
|
||||
error: function(e) {
|
||||
// if server is not available, just continue
|
||||
// and read the user's keys from local storage
|
||||
console.log('Server unavailable: keys were not synced to server!');
|
||||
callback(keyId);
|
||||
}
|
||||
});
|
||||
|
||||
// then upload private key
|
||||
|
||||
function uploadPrivateKeys() {
|
||||
server.xhr({
|
||||
type: 'POST',
|
||||
uri: '/ws/privateKeys',
|
||||
contentType: 'application/json',
|
||||
expected: 201,
|
||||
body: jsonPrivateKey,
|
||||
success: function(resp) {
|
||||
// read the user's keys from local storage
|
||||
callback(keyId);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the keypair from the server and import them into localstorage
|
||||
*/
|
||||
self.fetchKeys = function(email, keyId, callback, errCallback) {
|
||||
var base64Key = window.btoa(keyId);
|
||||
var encodedKeyId = encodeURIComponent(base64Key);
|
||||
|
||||
// get public key
|
||||
server.xhr({
|
||||
type: 'GET',
|
||||
uri: '/ws/publicKeys?keyId=' + encodedKeyId,
|
||||
expected: 200,
|
||||
success: function(pubKey) {
|
||||
getPrivateKey(pubKey);
|
||||
},
|
||||
error: function(e) {
|
||||
// if server is not available, just continue
|
||||
console.log('Server unavailable: keys could not be fetched from server!');
|
||||
errCallback(e);
|
||||
}
|
||||
});
|
||||
|
||||
// get private key
|
||||
|
||||
function getPrivateKey(pubKey) {
|
||||
server.xhr({
|
||||
type: 'GET',
|
||||
uri: '/ws/privateKeys?keyId=' + encodedKeyId,
|
||||
expected: 200,
|
||||
success: function(privKey) {
|
||||
// import keys
|
||||
self.importKeys(pubKey.asciiArmored, privKey.asciiArmored, email);
|
||||
callback({
|
||||
privateKey: privKey,
|
||||
publicKey: pubKey
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the current user's private key
|
||||
*/
|
||||
self.getPrivateKey = function() {
|
||||
if (!privateKey) {
|
||||
return undefined;
|
||||
}
|
||||
return privateKey.armored;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the current user's public key
|
||||
*/
|
||||
self.getPublicKey = function() {
|
||||
if (!publicKey) {
|
||||
return undefined;
|
||||
}
|
||||
return publicKey.armored;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the current user's base64 encoded public key ID
|
||||
*/
|
||||
self.getPublicKeyIdBase64 = function() {
|
||||
return window.btoa(publicKey.keyId);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the user's passphrase for decrypting their private key
|
||||
*/
|
||||
self.setPassphrase = function(pass) {
|
||||
passphrase = pass;
|
||||
};
|
||||
|
||||
/**
|
||||
* Store the passphrase for the current session
|
||||
*/
|
||||
self.rememberPassphrase = function(keyId) {
|
||||
var base64KeyId = window.btoa(keyId);
|
||||
window.sessionStorage.setItem(base64KeyId + 'Passphrase', passphrase);
|
||||
};
|
||||
|
||||
//
|
||||
// Asymmetric crypto
|
||||
//
|
||||
|
||||
/**
|
||||
* Encrypt a string
|
||||
* @param customPubKey [PublicKey] (optional) another user's public key for sharing
|
||||
*/
|
||||
self.asymmetricEncrypt = function(plaintext, customPubKey) {
|
||||
var pub_key = null;
|
||||
if (customPubKey) {
|
||||
// use a custom set public for e.g. or sharing
|
||||
pub_key = openpgp.read_publicKey(customPubKey);
|
||||
} else {
|
||||
// use the user's local public key
|
||||
pub_key = openpgp.read_publicKey(publicKey.armored);
|
||||
}
|
||||
|
||||
var ciphertext = openpgp.write_encrypted_message(pub_key, window.btoa(plaintext));
|
||||
return ciphertext;
|
||||
};
|
||||
|
||||
/**
|
||||
* Decrypt a string
|
||||
*/
|
||||
self.asymmetricDecrypt = function(ciphertext) {
|
||||
var priv_key = openpgp.read_privateKey(privateKey.armored);
|
||||
|
||||
var msg = openpgp.read_message(ciphertext);
|
||||
var keymat = null;
|
||||
var sesskey = null;
|
||||
|
||||
// Find the private (sub)key for the session key of the message
|
||||
for (var i = 0; i < msg[0].sessionKeys.length; i++) {
|
||||
if (priv_key[0].privateKeyPacket.publicKey.getKeyId() == msg[0].sessionKeys[i].keyId.bytes) {
|
||||
keymat = {
|
||||
key: priv_key[0],
|
||||
keymaterial: priv_key[0].privateKeyPacket
|
||||
};
|
||||
sesskey = msg[0].sessionKeys[i];
|
||||
break;
|
||||
}
|
||||
for (var j = 0; j < priv_key[0].subKeys.length; j++) {
|
||||
if (priv_key[0].subKeys[j].publicKey.getKeyId() == msg[0].sessionKeys[i].keyId.bytes) {
|
||||
keymat = {
|
||||
key: priv_key[0],
|
||||
keymaterial: priv_key[0].subKeys[j]
|
||||
};
|
||||
sesskey = msg[0].sessionKeys[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (keymat !== null) {
|
||||
if (!keymat.keymaterial.decryptSecretMPIs(passphrase)) {
|
||||
throw "Passphrase for secrect key was incorrect!";
|
||||
}
|
||||
|
||||
var decrypted = msg[0].decrypt(keymat, sesskey);
|
||||
return window.atob(decrypted);
|
||||
|
||||
} else {
|
||||
throw "No private key found!";
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* This function needs to be implemented, since it is used by the openpgp utils
|
||||
*/
|
||||
|
||||
function showMessages(str) {}
|
@ -54,23 +54,23 @@
|
||||
this.formatDate = function(date) {
|
||||
var year = "" + date.getFullYear();
|
||||
var month = "" + (date.getMonth() + 1);
|
||||
if (month.length == 1) {
|
||||
if (month.length === 1) {
|
||||
month = "0" + month;
|
||||
}
|
||||
var day = "" + date.getDate();
|
||||
if (day.length == 1) {
|
||||
if (day.length === 1) {
|
||||
day = "0" + day;
|
||||
}
|
||||
var hour = "" + date.getHours();
|
||||
if (hour.length == 1) {
|
||||
if (hour.length === 1) {
|
||||
hour = "0" + hour;
|
||||
}
|
||||
var minute = "" + date.getMinutes();
|
||||
if (minute.length == 1) {
|
||||
if (minute.length === 1) {
|
||||
minute = "0" + minute;
|
||||
}
|
||||
var second = "" + date.getSeconds();
|
||||
if (second.length == 1) {
|
||||
if (second.length === 1) {
|
||||
second = "0" + second;
|
||||
}
|
||||
return year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second;
|
||||
|
@ -1,70 +0,0 @@
|
||||
module("PGP Crypto");
|
||||
|
||||
var pgp_test = {
|
||||
keyID: null,
|
||||
keySize: 1024
|
||||
};
|
||||
|
||||
asyncTest("Init", 1, function() {
|
||||
// init dependencies
|
||||
pgp_test.util = new app.crypto.Util(window);
|
||||
pgp_test.crypto = new app.crypto.PGP(window, openpgp, util, null);
|
||||
pgp_test.crypto.setPassphrase('asdf');
|
||||
ok(pgp_test.crypto, 'PGP crypto');
|
||||
|
||||
pgp_test.helperEncrDecr = function(crypto, keyId, plaintext) {
|
||||
if (!crypto.getPublicKey()) {
|
||||
crypto.readKeys(keyId);
|
||||
}
|
||||
|
||||
console.log('plaintext size [bytes]: ' + plaintext.length);
|
||||
|
||||
var startTime = (new Date).getTime();
|
||||
var ct = crypto.asymmetricEncrypt(plaintext);
|
||||
var diff = (new Date).getTime() - startTime;
|
||||
|
||||
console.log('Time taken for encryption [ms]: ' + diff);
|
||||
ok(ct, "ciphertext: see console output for benchmark");
|
||||
console.log('ciphertext size [bytes]: ' + ct.length);
|
||||
|
||||
var decrStart = (new Date).getTime();
|
||||
var pt = crypto.asymmetricDecrypt(ct);
|
||||
var decrDiff = (new Date).getTime() - decrStart;
|
||||
|
||||
console.log('Time taken for decryption [ms]: ' + decrDiff);
|
||||
ok(pt, "decrypted: see console output for benchmark");
|
||||
equal(pt, plaintext, "Decrypted should be the same as the plaintext");
|
||||
};
|
||||
|
||||
start();
|
||||
});
|
||||
|
||||
asyncTest("Generate keypair, De/Encrypt", 7, function() {
|
||||
var startTime = (new Date).getTime();
|
||||
var keys = pgp_test.crypto.generateKeys(pgp_test.keySize);
|
||||
var diff = (new Date).getTime() - startTime;
|
||||
|
||||
pgp_test.keyID = keys.privateKey.getKeyId();
|
||||
pgp_test.crypto.readKeys(pgp_test.keyID);
|
||||
|
||||
console.log('Time taken for key generation [ms]: ' + diff + ' (' + pgp_test.keySize + ' bit RSA keypair)');
|
||||
ok(pgp_test.crypto.getPrivateKey());
|
||||
ok(pgp_test.crypto.getPrivateKey().indexOf('-----BEGIN PGP PRIVATE KEY BLOCK-----') === 0);
|
||||
ok(pgp_test.crypto.getPublicKey());
|
||||
ok(pgp_test.crypto.getPublicKey().indexOf('-----BEGIN PGP PUBLIC KEY BLOCK-----') === 0);
|
||||
|
||||
pgp_test.helperEncrDecr(pgp_test.crypto, pgp_test.keyID, '06a9214036b8a15b512e03d534120006');
|
||||
|
||||
start();
|
||||
|
||||
// pgp_test.crypto.exportKeys(function(url) {
|
||||
// ok(url, 'export url');
|
||||
//
|
||||
// $.get(url, function(data) {
|
||||
// ok(data.indexOf('-----BEGIN PGP PUBLIC KEY BLOCK-----') !== -1, 'exportd public key');
|
||||
// ok(data.indexOf('-----END PGP PRIVATE KEY BLOCK-----') !== -1, 'export private key');
|
||||
//
|
||||
// start();
|
||||
// });
|
||||
// });
|
||||
});
|
@ -1,3 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
module("Crypto Api");
|
||||
|
||||
var crypto_test = {
|
||||
@ -40,30 +42,33 @@ asyncTest("Init with keypair", 1, function() {
|
||||
rsaKeySize: crypto_test.rsaKeySize,
|
||||
storedKeypair: crypto_test.generatedKeypair
|
||||
}, function(err, generatedKeypair) {
|
||||
ok(!err, 'Init crypto with keypair input');
|
||||
ok(!err && !generatedKeypair, 'Init crypto with keypair input');
|
||||
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest("PBKDF2 (Async/Worker)", 1, function() {
|
||||
crypto_test.crypto.deriveKey(crypto_test.password, crypto_test.keySize, function(key) {
|
||||
asyncTest("PBKDF2 (Async/Worker)", 2, function() {
|
||||
crypto_test.crypto.deriveKey(crypto_test.password, crypto_test.keySize, function(err, key) {
|
||||
ok(!err);
|
||||
equal(crypto_test.util.base642Str(key).length * 8, crypto_test.keySize, 'Keysize ' + crypto_test.keySize);
|
||||
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest("AES en/decrypt (Async/Worker)", 2, function() {
|
||||
asyncTest("AES en/decrypt (Async/Worker)", 4, function() {
|
||||
var secret = 'Big secret';
|
||||
|
||||
var key = crypto_test.util.random(crypto_test.keySize);
|
||||
var iv = crypto_test.util.random(crypto_test.ivSize);
|
||||
|
||||
crypto_test.crypto.aesEncrypt(secret, key, iv, function(ciphertext) {
|
||||
crypto_test.crypto.aesEncrypt(secret, key, iv, function(err, ciphertext) {
|
||||
ok(!err);
|
||||
ok(ciphertext, 'Encrypt item');
|
||||
|
||||
crypto_test.crypto.aesDecrypt(ciphertext, key, iv, function(decrypted) {
|
||||
crypto_test.crypto.aesDecrypt(ciphertext, key, iv, function(err, decrypted) {
|
||||
ok(!err);
|
||||
equal(decrypted, secret, 'Decrypt item');
|
||||
|
||||
start();
|
||||
|
@ -12,6 +12,7 @@
|
||||
<script>
|
||||
// clear session storage of failed tests, so async order is correct after fail & refresh
|
||||
window.sessionStorage.clear();
|
||||
//window.Worker = undefined;
|
||||
</script>
|
||||
|
||||
<!-- dependencies -->
|
||||
|
Loading…
Reference in New Issue
Block a user