Refactor web worker async proxy to use promises.

This commit is contained in:
Tankred Hase 2014-10-01 21:18:05 +02:00
parent 7f2573c77d
commit f08fc0a4f7
5 changed files with 264 additions and 273 deletions

View File

@ -239,8 +239,8 @@ function generateKeyPair(options) {
/**
* Are we in a browser and do we support worker?
*/
function useWorker(callback) {
if (typeof window === 'undefined' || !window.Worker || typeof callback !== 'function') {
function useWorker() {
if (typeof window === 'undefined' || !window.Worker) {
return false;
}

View File

@ -24,11 +24,12 @@
* @module async_proxy
*/
'use strict';
var crypto = require('../crypto'),
packet = require('../packet'),
key = require('../key.js'),
type_keyid = require('../type/keyid.js'),
enums = require('../enums.js');
type_keyid = require('../type/keyid.js');
var INITIAL_RANDOM_SEED = 50000, // random bytes seeded to worker
RANDOM_SEED_REQUEST = 20000; // random bytes seeded after worker request
@ -49,6 +50,24 @@ function AsyncProxy(path) {
this.tasks = [];
}
/**
* Command pattern that wraps synchronous code into a promise
* @param {Object} self The current this
* @param {function} cmd The synchronous function with a return value
* to be wrapped in a promise
* @return {Promise} The promise wrapped around cmd
*/
AsyncProxy.prototype.execute = function(cmd) {
var self = this;
var promise = new Promise(function(resolve, reject) {
cmd();
self.tasks.push({ resolve:resolve, reject:reject });
});
return promise;
};
/**
* Message handling
*/
@ -56,7 +75,13 @@ AsyncProxy.prototype.onMessage = function(event) {
var msg = event.data;
switch (msg.event) {
case 'method-return':
this.tasks.shift()(msg.err ? new Error(msg.err) : null, msg.data);
if (msg.err) {
// fail
this.tasks.shift().reject(new Error(msg.err));
} else {
// success
this.tasks.shift().resolve(msg.data);
}
break;
case 'request-seed':
this.seedRandom(RANDOM_SEED_REQUEST);
@ -98,21 +123,23 @@ AsyncProxy.prototype.terminate = function() {
* Encrypts message text with keys
* @param {(Array<module:key~Key>|module:key~Key)} keys array of keys or single key, used to encrypt the message
* @param {String} text message as native JavaScript string
* @param {Function} callback receives encrypted ASCII armored message
*/
AsyncProxy.prototype.encryptMessage = function(keys, text, callback) {
if (!keys.length) {
keys = [keys];
}
keys = keys.map(function(key) {
return key.toPacketlist();
AsyncProxy.prototype.encryptMessage = function(keys, text) {
var self = this;
return self.execute(function() {
if (!keys.length) {
keys = [keys];
}
keys = keys.map(function(key) {
return key.toPacketlist();
});
self.worker.postMessage({
event: 'encrypt-message',
keys: keys,
text: text
});
});
this.worker.postMessage({
event: 'encrypt-message',
keys: keys,
text: text
});
this.tasks.push(callback);
};
/**
@ -120,40 +147,43 @@ AsyncProxy.prototype.encryptMessage = function(keys, text, callback) {
* @param {(Array<module:key~Key>|module:key~Key)} publicKeys array of keys or single key, used to encrypt the message
* @param {module:key~Key} privateKey private key with decrypted secret key data for signing
* @param {String} text message as native JavaScript string
* @param {Function} callback receives encrypted ASCII armored message
*/
AsyncProxy.prototype.signAndEncryptMessage = function(publicKeys, privateKey, text, callback) {
if (!publicKeys.length) {
publicKeys = [publicKeys];
}
publicKeys = publicKeys.map(function(key) {
return key.toPacketlist();
AsyncProxy.prototype.signAndEncryptMessage = function(publicKeys, privateKey, text) {
var self = this;
return self.execute(function() {
if (!publicKeys.length) {
publicKeys = [publicKeys];
}
publicKeys = publicKeys.map(function(key) {
return key.toPacketlist();
});
privateKey = privateKey.toPacketlist();
self.worker.postMessage({
event: 'sign-and-encrypt-message',
publicKeys: publicKeys,
privateKey: privateKey,
text: text
});
});
privateKey = privateKey.toPacketlist();
this.worker.postMessage({
event: 'sign-and-encrypt-message',
publicKeys: publicKeys,
privateKey: privateKey,
text: text
});
this.tasks.push(callback);
};
/**
* Decrypts message
* @param {module:key~Key} privateKey private key with decrypted secret key data
* @param {module:message~Message} message the message object with the encrypted data
* @param {Function} callback receives decrypted message as as native JavaScript string
* or null if no literal data found
*/
AsyncProxy.prototype.decryptMessage = function(privateKey, message, callback) {
privateKey = privateKey.toPacketlist();
this.worker.postMessage({
event: 'decrypt-message',
privateKey: privateKey,
message: message
AsyncProxy.prototype.decryptMessage = function(privateKey, message) {
var self = this;
return self.execute(function() {
privateKey = privateKey.toPacketlist();
self.worker.postMessage({
event: 'decrypt-message',
privateKey: privateKey,
message: message
});
});
this.tasks.push(callback);
};
/**
@ -161,82 +191,91 @@ AsyncProxy.prototype.decryptMessage = function(privateKey, message, callback) {
* @param {module:key~Key} privateKey private key with decrypted secret key data
* @param {(Array<module:key~Key>|module:key~Key)} publicKeys array of keys or single key to verify signatures
* @param {module:message~Message} message the message object with signed and encrypted data
* @param {Function} callback receives decrypted message as as native JavaScript string
* with verified signatures or null if no literal data found
*/
AsyncProxy.prototype.decryptAndVerifyMessage = function(privateKey, publicKeys, message, callback) {
privateKey = privateKey.toPacketlist();
if (!publicKeys.length) {
publicKeys = [publicKeys];
}
publicKeys = publicKeys.map(function(key) {
return key.toPacketlist();
});
this.worker.postMessage({
event: 'decrypt-and-verify-message',
privateKey: privateKey,
publicKeys: publicKeys,
message: message
});
this.tasks.push(function(err, data) {
if (data) {
AsyncProxy.prototype.decryptAndVerifyMessage = function(privateKey, publicKeys, message) {
var self = this;
var promise = new Promise(function(resolve, reject) {
privateKey = privateKey.toPacketlist();
if (!publicKeys.length) {
publicKeys = [publicKeys];
}
publicKeys = publicKeys.map(function(key) {
return key.toPacketlist();
});
self.worker.postMessage({
event: 'decrypt-and-verify-message',
privateKey: privateKey,
publicKeys: publicKeys,
message: message
});
self.tasks.push({ resolve:function(data) {
data.signatures = data.signatures.map(function(sig) {
sig.keyid = type_keyid.fromClone(sig.keyid);
return sig;
});
}
callback(err, data);
resolve(data);
}, reject:reject });
});
return promise;
};
/**
* Signs a cleartext message
* @param {(Array<module:key~Key>|module:key~Key)} privateKeys array of keys or single key, with decrypted secret key data to sign cleartext
* @param {String} text cleartext
* @param {Function} callback receives ASCII armored message
*/
AsyncProxy.prototype.signClearMessage = function(privateKeys, text, callback) {
if (!privateKeys.length) {
privateKeys = [privateKeys];
}
privateKeys = privateKeys.map(function(key) {
return key.toPacketlist();
AsyncProxy.prototype.signClearMessage = function(privateKeys, text) {
var self = this;
return self.execute(function() {
if (!privateKeys.length) {
privateKeys = [privateKeys];
}
privateKeys = privateKeys.map(function(key) {
return key.toPacketlist();
});
self.worker.postMessage({
event: 'sign-clear-message',
privateKeys: privateKeys,
text: text
});
});
this.worker.postMessage({
event: 'sign-clear-message',
privateKeys: privateKeys,
text: text
});
this.tasks.push(callback);
};
/**
* Verifies signatures of cleartext signed message
* @param {(Array<module:key~Key>|module:key~Key)} publicKeys array of keys or single key, to verify signatures
* @param {module:cleartext~CleartextMessage} message cleartext message object with signatures
* @param {Function} callback receives cleartext with status of verified signatures
*/
AsyncProxy.prototype.verifyClearSignedMessage = function(publicKeys, message, callback) {
if (!publicKeys.length) {
publicKeys = [publicKeys];
}
publicKeys = publicKeys.map(function(key) {
return key.toPacketlist();
});
this.worker.postMessage({
event: 'verify-clear-signed-message',
publicKeys: publicKeys,
message: message
});
this.tasks.push(function(err, data) {
if (data) {
AsyncProxy.prototype.verifyClearSignedMessage = function(publicKeys, message) {
var self = this;
var promise = new Promise(function(resolve, reject) {
if (!publicKeys.length) {
publicKeys = [publicKeys];
}
publicKeys = publicKeys.map(function(key) {
return key.toPacketlist();
});
self.worker.postMessage({
event: 'verify-clear-signed-message',
publicKeys: publicKeys,
message: message
});
self.tasks.push({ resolve:function(data) {
data.signatures = data.signatures.map(function(sig) {
sig.keyid = type_keyid.fromClone(sig.keyid);
return sig;
});
}
callback(err, data);
resolve(data);
}, reject:reject });
});
return promise;
};
/**
@ -247,42 +286,50 @@ AsyncProxy.prototype.verifyClearSignedMessage = function(publicKeys, message, ca
* @param {Integer} numBits number of bits for the key creation. (should be 1024+, generally)
* @param {String} userId assumes already in form of "User Name <username@email.com>"
* @param {String} passphrase The passphrase used to encrypt the resulting private key
* @param {Function} callback receives object with key and public and private armored texts
*/
AsyncProxy.prototype.generateKeyPair = function(options, callback) {
this.worker.postMessage({
event: 'generate-key-pair',
options: options
});
this.tasks.push(function(err, data) {
if (data) {
AsyncProxy.prototype.generateKeyPair = function(options) {
var self = this;
var promise = new Promise(function(resolve, reject) {
self.worker.postMessage({
event: 'generate-key-pair',
options: options
});
self.tasks.push({ resolve:function(data) {
var packetlist = packet.List.fromStructuredClone(data.key);
data.key = new key.Key(packetlist);
}
callback(err, data);
resolve(data);
}, reject:reject });
});
return promise;
};
/**
* Decrypts secret part of all secret key packets of key.
* @param {module:key~Key} privateKey private key with encrypted secret key data
* @param {String} password password to unlock the key
* @param {Function} callback receives decrypted key
*/
AsyncProxy.prototype.decryptKey = function(privateKey, password, callback) {
privateKey = privateKey.toPacketlist();
this.worker.postMessage({
event: 'decrypt-key',
privateKey: privateKey,
password: password
});
this.tasks.push(function(err, data) {
if (data) {
AsyncProxy.prototype.decryptKey = function(privateKey, password) {
var self = this;
var promise = new Promise(function(resolve, reject) {
privateKey = privateKey.toPacketlist();
self.worker.postMessage({
event: 'decrypt-key',
privateKey: privateKey,
password: password
});
self.tasks.push({ resolve:function(data) {
var packetlist = packet.List.fromStructuredClone(data);
data = new key.Key(packetlist);
}
callback(err, data);
resolve(data);
}, reject:reject });
});
return promise;
};
/**
@ -290,23 +337,27 @@ AsyncProxy.prototype.decryptKey = function(privateKey, password, callback) {
* @param {module:key~Key} privateKey private key with encrypted secret key data
* @param {Array<module:type/keyid>} keyIds
* @param {String} password password to unlock the key
* @param {Function} callback receives decrypted key
*/
AsyncProxy.prototype.decryptKeyPacket = function(privateKey, keyIds, password, callback) {
privateKey = privateKey.toPacketlist();
this.worker.postMessage({
event: 'decrypt-key-packet',
privateKey: privateKey,
keyIds: keyIds,
password: password
});
this.tasks.push(function(err, data) {
if (data) {
AsyncProxy.prototype.decryptKeyPacket = function(privateKey, keyIds, password) {
var self = this;
var promise = new Promise(function(resolve, reject) {
privateKey = privateKey.toPacketlist();
self.worker.postMessage({
event: 'decrypt-key-packet',
privateKey: privateKey,
keyIds: keyIds,
password: password
});
self.tasks.push({ resolve:function(data) {
var packetlist = packet.List.fromStructuredClone(data);
data = new key.Key(packetlist);
}
callback(err, data);
resolve(data);
}, reject:reject });
});
return promise;
};
module.exports = AsyncProxy;

View File

@ -5,7 +5,7 @@
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3.0 of the License, or (at your option) any later version.
//
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
@ -24,11 +24,12 @@ var MAX_SIZE_RANDOM_BUFFER = 60000;
window.openpgp.crypto.random.randomBuffer.init(MAX_SIZE_RANDOM_BUFFER);
onmessage = function (event) {
self.onmessage = function (event) {
var data = null,
err = null,
msg = event.data,
correct = false;
switch (msg.event) {
case 'seed-random':
if (!(msg.buf instanceof Uint8Array)) {
@ -37,93 +38,78 @@ onmessage = function (event) {
window.openpgp.crypto.random.randomBuffer.set(msg.buf);
break;
case 'encrypt-message':
try {
if (!msg.keys.length) {
msg.keys = [msg.keys];
}
msg.keys = msg.keys.map(packetlistCloneToKey);
data = window.openpgp.encryptMessage(msg.keys, msg.text);
} catch (e) {
err = e.message;
if (!msg.keys.length) {
msg.keys = [msg.keys];
}
response({event: 'method-return', data: data, err: err});
msg.keys = msg.keys.map(packetlistCloneToKey);
window.openpgp.encryptMessage(msg.keys, msg.text).then(function(data) {
response({event: 'method-return', data: data});
}).catch(function(e) {
response({event: 'method-return', err: e.message});
});
break;
case 'sign-and-encrypt-message':
try {
if (!msg.publicKeys.length) {
msg.publicKeys = [msg.publicKeys];
}
msg.publicKeys = msg.publicKeys.map(packetlistCloneToKey);
msg.privateKey = packetlistCloneToKey(msg.privateKey);
data = window.openpgp.signAndEncryptMessage(msg.publicKeys, msg.privateKey, msg.text);
} catch (e) {
err = e.message;
if (!msg.publicKeys.length) {
msg.publicKeys = [msg.publicKeys];
}
response({event: 'method-return', data: data, err: err});
msg.publicKeys = msg.publicKeys.map(packetlistCloneToKey);
msg.privateKey = packetlistCloneToKey(msg.privateKey);
window.openpgp.signAndEncryptMessage(msg.publicKeys, msg.privateKey, msg.text).then(function(data) {
response({event: 'method-return', data: data});
}).catch(function(e) {
response({event: 'method-return', err: e.message});
});
break;
case 'decrypt-message':
try {
msg.privateKey = packetlistCloneToKey(msg.privateKey);
msg.message = packetlistCloneToMessage(msg.message.packets);
data = window.openpgp.decryptMessage(msg.privateKey, msg.message);
} catch (e) {
err = e.message;
}
response({event: 'method-return', data: data, err: err});
msg.privateKey = packetlistCloneToKey(msg.privateKey);
msg.message = packetlistCloneToMessage(msg.message.packets);
window.openpgp.decryptMessage(msg.privateKey, msg.message).then(function(data) {
response({event: 'method-return', data: data});
}).catch(function(e) {
response({event: 'method-return', err: e.message});
});
break;
case 'decrypt-and-verify-message':
try {
msg.privateKey = packetlistCloneToKey(msg.privateKey);
if (!msg.publicKeys.length) {
msg.publicKeys = [msg.publicKeys];
}
msg.publicKeys = msg.publicKeys.map(packetlistCloneToKey);
msg.message = packetlistCloneToMessage(msg.message.packets);
data = window.openpgp.decryptAndVerifyMessage(msg.privateKey, msg.publicKeys, msg.message);
} catch (e) {
err = e.message;
msg.privateKey = packetlistCloneToKey(msg.privateKey);
if (!msg.publicKeys.length) {
msg.publicKeys = [msg.publicKeys];
}
response({event: 'method-return', data: data, err: err});
msg.publicKeys = msg.publicKeys.map(packetlistCloneToKey);
msg.message = packetlistCloneToMessage(msg.message.packets);
window.openpgp.decryptAndVerifyMessage(msg.privateKey, msg.publicKeys, msg.message).then(function(data) {
response({event: 'method-return', data: data});
}).catch(function(e) {
response({event: 'method-return', err: e.message});
});
break;
case 'sign-clear-message':
try {
msg.privateKeys = msg.privateKeys.map(packetlistCloneToKey);
data = window.openpgp.signClearMessage(msg.privateKeys, msg.text);
} catch (e) {
err = e.message;
}
response({event: 'method-return', data: data, err: err});
msg.privateKeys = msg.privateKeys.map(packetlistCloneToKey);
window.openpgp.signClearMessage(msg.privateKeys, msg.text).then(function(data) {
response({event: 'method-return', data: data});
}).catch(function(e) {
response({event: 'method-return', err: e.message});
});
break;
case 'verify-clear-signed-message':
try {
if (!msg.publicKeys.length) {
msg.publicKeys = [msg.publicKeys];
}
msg.publicKeys = msg.publicKeys.map(packetlistCloneToKey);
var packetlist = window.openpgp.packet.List.fromStructuredClone(msg.message.packets);
msg.message = new window.openpgp.cleartext.CleartextMessage(msg.message.text, packetlist);
data = window.openpgp.verifyClearSignedMessage(msg.publicKeys, msg.message);
} catch (e) {
err = e.message;
if (!msg.publicKeys.length) {
msg.publicKeys = [msg.publicKeys];
}
response({event: 'method-return', data: data, err: err});
msg.publicKeys = msg.publicKeys.map(packetlistCloneToKey);
var packetlist = window.openpgp.packet.List.fromStructuredClone(msg.message.packets);
msg.message = new window.openpgp.cleartext.CleartextMessage(msg.message.text, packetlist);
window.openpgp.verifyClearSignedMessage(msg.publicKeys, msg.message).then(function(data) {
response({event: 'method-return', data: data});
}).catch(function(e) {
response({event: 'method-return', err: e.message});
});
break;
case 'generate-key-pair':
try {
window.openpgp.generateKeyPair(msg.options, function(error, data) {
if (error) {
err = error.message;
response({event: 'method-return', data: data, err: err});
return;
}
data.key = data.key.toPacketlist();
response({event: 'method-return', data: data, err: err});
});
} catch (e) {
err = e.message;
response({event: 'method-return', data: data, err: err});
}
window.openpgp.generateKeyPair(msg.options).then(function(data) {
data.key = data.key.toPacketlist();
response({event: 'method-return', data: data});
}).catch(function(e) {
response({event: 'method-return', err: e.message});
});
break;
case 'decrypt-key':
try {

View File

@ -18,6 +18,7 @@
<script src="lib/mocha.js"></script>
<script>
mocha.setup('bdd');
mocha.timeout(20000);
</script>
<script src="lib/unittests-bundle.js"></script>
<script>

View File

@ -184,8 +184,7 @@ describe('High level API', function() {
describe('Encryption', function() {
it('RSA: encryptMessage async', function (done) {
openpgp.encryptMessage([pubKeyRSA], plaintext, function(err, data) {
expect(err).to.not.exist;
openpgp.encryptMessage([pubKeyRSA], plaintext).then(function(data) {
expect(data).to.exist;
expect(data).to.match(/^-----BEGIN PGP MESSAGE/);
var msg = openpgp.message.readArmored(data);
@ -195,8 +194,7 @@ describe('High level API', function() {
});
it('RSA: encryptMessage one key async', function (done) {
openpgp.encryptMessage(pubKeyRSA, plaintext, function(err, data) {
expect(err).to.not.exist;
openpgp.encryptMessage(pubKeyRSA, plaintext).then(function(data) {
expect(data).to.exist;
expect(data).to.match(/^-----BEGIN PGP MESSAGE/);
var msg = openpgp.message.readArmored(data);
@ -205,25 +203,8 @@ describe('High level API', function() {
});
});
it('RSA: encryptMessage sync', function () {
var msg = openpgp.encryptMessage([pubKeyRSA], plaintext);
expect(msg).to.exist;
expect(msg).to.match(/^-----BEGIN PGP MESSAGE/);
msg = openpgp.message.readArmored(msg);
expect(msg).to.be.an.instanceof(openpgp.message.Message);
});
it('RSA: encryptMessage one key sync', function () {
var msg = openpgp.encryptMessage(pubKeyRSA, plaintext);
expect(msg).to.exist;
expect(msg).to.match(/^-----BEGIN PGP MESSAGE/);
msg = openpgp.message.readArmored(msg);
expect(msg).to.be.an.instanceof(openpgp.message.Message);
});
it('ELG: encryptMessage async', function (done) {
openpgp.encryptMessage([pubKeyDE], plaintext, function(err, data) {
expect(err).to.not.exist;
openpgp.encryptMessage([pubKeyDE], plaintext).then(function(data) {
expect(data).to.exist;
expect(data).to.match(/^-----BEGIN PGP MESSAGE/);
var msg = openpgp.message.readArmored(data);
@ -232,14 +213,6 @@ describe('High level API', function() {
});
});
it('ELG: encryptMessage sync', function () {
var msg = openpgp.encryptMessage([pubKeyDE], plaintext);
expect(msg).to.exist;
expect(msg).to.match(/^-----BEGIN PGP MESSAGE/);
msg = openpgp.message.readArmored(msg);
expect(msg).to.be.an.instanceof(openpgp.message.Message);
});
});
describe('Decryption', function() {
@ -254,35 +227,21 @@ describe('High level API', function() {
});
it('RSA: decryptMessage async', function (done) {
openpgp.decryptMessage(privKeyRSA, msgRSA, function(err, data) {
expect(err).to.not.exist;
openpgp.decryptMessage(privKeyRSA, msgRSA).then(function(data) {
expect(data).to.exist;
expect(data).to.equal(plaintext);
done();
});
});
it('RSA: decryptMessage sync', function () {
var text = openpgp.decryptMessage(privKeyRSA, msgRSA);
expect(text).to.exist;
expect(text).to.equal(plaintext);
});
it('ELG: decryptMessage async', function (done) {
openpgp.decryptMessage(privKeyDE, msgDE, function(err, data) {
expect(err).to.not.exist;
openpgp.decryptMessage(privKeyDE, msgDE).then(function(data) {
expect(data).to.exist;
expect(data).to.equal(plaintext);
done();
});
});
it('ELG: decryptMessage sync', function () {
var text = openpgp.decryptMessage(privKeyDE, msgDE);
expect(text).to.exist;
expect(text).to.equal(plaintext);
});
});
function verifySignature(data, privKey) {
@ -304,8 +263,7 @@ describe('High level API', function() {
});
it('RSA: decryptAndVerifyMessage async', function (done) {
openpgp.decryptAndVerifyMessage(privKeyRSA, [pubKeyRSA], msgRSA, function(err, data) {
expect(err).to.not.exist;
openpgp.decryptAndVerifyMessage(privKeyRSA, [pubKeyRSA], msgRSA).then(function(data) {
expect(data).to.exist;
verifySignature(data, privKeyRSA);
done();
@ -313,8 +271,7 @@ describe('High level API', function() {
});
it('ELG: decryptAndVerifyMessage async', function (done) {
openpgp.decryptAndVerifyMessage(privKeyDE, [pubKeyDE], msgDE, function(err, data) {
expect(err).to.not.exist;
openpgp.decryptAndVerifyMessage(privKeyDE, [pubKeyDE], msgDE).then(function(data) {
expect(data).to.exist;
verifySignature(data, privKeyDE);
done();
@ -330,13 +287,13 @@ describe('High level API', function() {
});
it('RSA: signAndEncryptMessage async', function (done) {
openpgp.signAndEncryptMessage([pubKeyRSA], privKeyRSA, plaintext, function(err, data) {
expect(err).to.not.exist;
openpgp.signAndEncryptMessage([pubKeyRSA], privKeyRSA, plaintext).then(function(data) {
expect(data).to.exist;
expect(data).to.match(/^-----BEGIN PGP MESSAGE/);
var msg = openpgp.message.readArmored(data);
expect(msg).to.be.an.instanceof(openpgp.message.Message);
var decrypted = openpgp.decryptAndVerifyMessage(privKeyRSA, [pubKeyRSA], msg);
return openpgp.decryptAndVerifyMessage(privKeyRSA, [pubKeyRSA], msg);
}).then(function(decrypted) {
verifySignature(decrypted, privKeyRSA);
done();
});
@ -352,8 +309,7 @@ describe('High level API', function() {
});
it('RSA: signClearMessage async', function (done) {
openpgp.signClearMessage([privKeyRSA], plaintext, function(err, data) {
expect(err).to.not.exist;
openpgp.signClearMessage([privKeyRSA], plaintext).then(function(data) {
expect(data).to.exist;
expect(data).to.match(/-----BEGIN PGP SIGNED MESSAGE-----/);
var msg = openpgp.message.readArmored(data);
@ -363,8 +319,7 @@ describe('High level API', function() {
});
it('DSA: signClearMessage async', function (done) {
openpgp.signClearMessage([privKeyDE], plaintext, function(err, data) {
expect(err).to.not.exist;
openpgp.signClearMessage([privKeyDE], plaintext).then(function(data) {
expect(data).to.exist;
expect(data).to.match(/-----BEGIN PGP SIGNED MESSAGE-----/);
var msg = openpgp.message.readArmored(data);
@ -374,10 +329,10 @@ describe('High level API', function() {
});
it('RSA: verifyClearSignedMessage async', function (done) {
var signed = openpgp.signClearMessage([privKeyRSA], plaintext);
signed = openpgp.cleartext.readArmored(signed);
openpgp.verifyClearSignedMessage([pubKeyRSA], signed, function(err, data) {
expect(err).to.not.exist;
openpgp.signClearMessage([privKeyRSA], plaintext).then(function(signed) {
signed = openpgp.cleartext.readArmored(signed);
return openpgp.verifyClearSignedMessage([pubKeyRSA], signed);
}).then(function(data) {
expect(data).to.exist;
verifySignature(data, privKeyRSA);
done();
@ -391,8 +346,7 @@ describe('High level API', function() {
before(initKeys);
it('Signing with not decrypted key gives error', function (done) {
openpgp.signClearMessage([privKeyRSA], plaintext, function(err, data) {
expect(data).to.not.exist;
openpgp.signClearMessage([privKeyRSA], plaintext).catch(function(err) {
expect(err).to.exist;
expect(err.message).to.equal('Private key is not decrypted.');
done();
@ -404,8 +358,7 @@ describe('High level API', function() {
wProxy.worker = new Worker('../dist/openpgp.worker.js');
wProxy.worker.onmessage = wProxy.onMessage.bind(wProxy);
wProxy.seedRandom(10);
wProxy.encryptMessage([pubKeyRSA], plaintext, function(err, data) {
expect(data).to.not.exist;
wProxy.encryptMessage([pubKeyRSA], plaintext).catch(function(err) {
expect(err).to.exist;
expect(err).to.eql(new Error('Random number buffer depleted'));
done();
@ -442,13 +395,13 @@ describe('High level API', function() {
it('Decrypt key', function (done) {
expect(privKeyRSA.primaryKey.isDecrypted).to.be.false;
expect(privKeyRSA.subKeys[0].subKey.isDecrypted).to.be.false;
proxy.decryptKey(privKeyRSA, 'hello world', function(err, data) {
expect(err).to.not.exist;
proxy.decryptKey(privKeyRSA, 'hello world').then(function(data) {
expect(data).to.exist;
expect(data).to.be.an.instanceof(openpgp.key.Key);
expect(data.primaryKey.isDecrypted).to.be.true;
expect(data.subKeys[0].subKey.isDecrypted).to.be.true;
var text = openpgp.decryptMessage(data, msg);
return openpgp.decryptMessage(data, msg);
}).then(function(text) {
expect(text).to.equal(plaintext);
done();
});
@ -458,20 +411,20 @@ describe('High level API', function() {
expect(privKeyRSA.primaryKey.isDecrypted).to.be.false;
expect(privKeyRSA.subKeys[0].subKey.isDecrypted).to.be.false;
var keyid = privKeyRSA.subKeys[0].subKey.getKeyId();
proxy.decryptKeyPacket(privKeyRSA, [keyid], 'hello world', function(err, data) {
expect(err).to.not.exist;
proxy.decryptKeyPacket(privKeyRSA, [keyid], 'hello world').then(function(data) {
expect(data).to.exist;
expect(data).to.be.an.instanceof(openpgp.key.Key);
expect(data.primaryKey.isDecrypted).to.be.false;
expect(data.subKeys[0].subKey.isDecrypted).to.be.true;
var text = openpgp.decryptMessage(data, msg);
return openpgp.decryptMessage(data, msg);
}).then(function(text) {
expect(text).to.equal(plaintext);
done();
});
});
it('Error on wrong password decryptKey', function (done) {
proxy.decryptKey(privKeyRSA, 'what?', function(err, data) {
proxy.decryptKey(privKeyRSA, 'what?').catch(function(err) {
expect(err).to.eql(new Error('Wrong password'));
done();
});
@ -479,7 +432,7 @@ describe('High level API', function() {
it('Error on wrong password decryptKeyPacket', function (done) {
var keyid = privKeyRSA.subKeys[0].subKey.getKeyId();
proxy.decryptKeyPacket(privKeyRSA, [keyid], 'what?', function(err, data) {
proxy.decryptKeyPacket(privKeyRSA, [keyid], 'what?').catch(function(err) {
expect(err).to.eql(new Error('Wrong password'));
done();
});