Web worker: add decryptKey and decryptKeyPacket methods to proxy

This commit is contained in:
Thomas Oberndörfer 2014-01-16 16:44:05 +01:00
parent a777371418
commit 37213e1654
3 changed files with 134 additions and 1 deletions

View File

@ -306,4 +306,50 @@ AsyncProxy.prototype.generateKeyPair = function(keyType, numBits, userId, passph
});
};
/**
* 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) {
var packetlist = packet.List.fromStructuredClone(data);
data = new key.Key(packetlist);
}
callback(err, data);
});
};
/**
* Decrypts secret part of key packets matching array of keyids.
* @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) {
var packetlist = packet.List.fromStructuredClone(data);
data = new key.Key(packetlist);
}
callback(err, data);
});
};
module.exports = AsyncProxy;

View File

@ -27,7 +27,8 @@ window.openpgp.crypto.random.randomBuffer.init(MAX_SIZE_RANDOM_BUFFER);
onmessage = function (event) {
var data = null,
err = null,
msg = event.data;
msg = event.data,
correct = false;
if (msg.seed) {
window.openpgp.crypto.random.randomBuffer.set(msg.seed);
}
@ -104,6 +105,35 @@ onmessage = function (event) {
}
response({event: 'method-return', data: data, err: err});
break;
case 'decrypt-key':
try {
msg.privateKey = packetlistCloneToKey(msg.privateKey);
correct = msg.privateKey.decrypt(msg.password);
if (correct) {
data = msg.privateKey.toPacketlist();
} else {
err = 'Wrong password';
}
} catch (e) {
err = e.message;
}
response({event: 'method-return', data: data, err: err});
break;
case 'decrypt-key-packet':
try {
msg.privateKey = packetlistCloneToKey(msg.privateKey);
msg.keyIds = msg.keyIds.map(window.openpgp.Keyid.fromClone);
correct = msg.privateKey.decryptKeyPacket(msg.keyIds, msg.password);
if (correct) {
data = msg.privateKey.toPacketlist();
} else {
err = 'Wrong password';
}
} catch (e) {
err = e.message;
}
response({event: 'method-return', data: data, err: err});
break;
default:
throw new Error('Unknown Worker Event.');
}

View File

@ -411,6 +411,63 @@ describe('High level API', function() {
});
describe('Decrypt secret key', function() {
var msg;
beforeEach(function() {
initKeys();
msg = openpgp.message.fromText(plaintext).encrypt([pubKeyRSA]);
});
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;
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);
expect(text).to.equal(plaintext);
done();
});
});
it('Decrypt key packet', function (done) {
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;
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);
expect(text).to.equal(plaintext);
done();
});
});
it('Error on wrong password decryptKey', function (done) {
proxy.decryptKey(privKeyRSA, 'what?', function(err, data) {
expect(err).to.eql(new Error('Wrong password'));
done();
});
});
it('Error on wrong password decryptKeyPacket', function (done) {
var keyid = privKeyRSA.subKeys[0].subKey.getKeyId();
proxy.decryptKeyPacket(privKeyRSA, [keyid], 'what?', function(err, data) {
expect(err).to.eql(new Error('Wrong password'));
done();
});
});
});
});
describe('Random Buffer', function() {