mirror of
https://github.com/moparisthebest/mail
synced 2024-11-22 17:02:17 -05:00
Fix signature verification for PGP messages
* Upgrade to OpenPGP.js v0.6.5 * Migrate PGP wrapper for breaking OpenPGP.js api changes * Change PGP wrapper decrypt api to return one signature arg * Change emailDao and keychainDao calls respectively * Fix tests * Add tests keygen with empty passphrase * Add tests to check PGP verification with wrong public key
This commit is contained in:
parent
0cd4430103
commit
049ac96954
@ -10,7 +10,7 @@ define(function(require) {
|
|||||||
|
|
||||||
var PGP = function() {
|
var PGP = function() {
|
||||||
openpgp.config.prefer_hash_algorithm = openpgp.enums.hash.sha256;
|
openpgp.config.prefer_hash_algorithm = openpgp.enums.hash.sha256;
|
||||||
openpgp.initWorker(config.workerPath + '/../lib/openpgp/openpgp.worker.min.js');
|
openpgp.initWorker(config.workerPath + '/../lib/openpgp/openpgp.worker.js');
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,7 +41,7 @@ define(function(require) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
callback(null, {
|
callback(null, {
|
||||||
keyId: keys.key.getKeyPacket().getKeyId().toHex().toUpperCase(),
|
keyId: keys.key.primaryKey.getKeyId().toHex().toUpperCase(),
|
||||||
privateKeyArmored: keys.privateKeyArmored,
|
privateKeyArmored: keys.privateKeyArmored,
|
||||||
publicKeyArmored: keys.publicKeyArmored
|
publicKeyArmored: keys.publicKeyArmored
|
||||||
});
|
});
|
||||||
@ -53,7 +53,7 @@ define(function(require) {
|
|||||||
*/
|
*/
|
||||||
PGP.prototype.getFingerprint = function(keyArmored) {
|
PGP.prototype.getFingerprint = function(keyArmored) {
|
||||||
function fingerprint(key) {
|
function fingerprint(key) {
|
||||||
return key.getKeyPacket().getFingerprint().toUpperCase();
|
return key.primaryKey.getFingerprint().toUpperCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
// process armored key input
|
// process armored key input
|
||||||
@ -78,7 +78,7 @@ define(function(require) {
|
|||||||
// process armored key input
|
// process armored key input
|
||||||
if (keyArmored) {
|
if (keyArmored) {
|
||||||
key = openpgp.key.readArmored(keyArmored).keys[0];
|
key = openpgp.key.readArmored(keyArmored).keys[0];
|
||||||
return key.getKeyPacket().getKeyId().toHex().toUpperCase();
|
return key.primaryKey.getKeyId().toHex().toUpperCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
// check already imported keys
|
// check already imported keys
|
||||||
@ -86,8 +86,8 @@ define(function(require) {
|
|||||||
throw new Error('Cannot read key IDs... keys not set!');
|
throw new Error('Cannot read key IDs... keys not set!');
|
||||||
}
|
}
|
||||||
|
|
||||||
pubKeyId = this._publicKey.getKeyPacket().getKeyId().toHex().toUpperCase();
|
pubKeyId = this._publicKey.primaryKey.getKeyId().toHex().toUpperCase();
|
||||||
privKeyId = this._privateKey.getKeyPacket().getKeyId().toHex().toUpperCase();
|
privKeyId = this._privateKey.primaryKey.getKeyId().toHex().toUpperCase();
|
||||||
|
|
||||||
if (!pubKeyId || !privKeyId || pubKeyId !== privKeyId) {
|
if (!pubKeyId || !privKeyId || pubKeyId !== privKeyId) {
|
||||||
throw new Error('Key IDs do not match!');
|
throw new Error('Key IDs do not match!');
|
||||||
@ -111,7 +111,7 @@ define(function(require) {
|
|||||||
throw new Error('Cannot read key params... keys not set!');
|
throw new Error('Cannot read key params... keys not set!');
|
||||||
}
|
}
|
||||||
|
|
||||||
packet = key.getKeyPacket();
|
packet = key.primaryKey;
|
||||||
|
|
||||||
// read user names and email addresses
|
// read user names and email addresses
|
||||||
userIds = [];
|
userIds = [];
|
||||||
@ -168,8 +168,8 @@ define(function(require) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check if keys have the same id
|
// check if keys have the same id
|
||||||
pubKeyId = this._publicKey.getKeyPacket().getKeyId().toHex();
|
pubKeyId = this._publicKey.primaryKey.getKeyId().toHex();
|
||||||
privKeyId = this._privateKey.getKeyPacket().getKeyId().toHex();
|
privKeyId = this._privateKey.primaryKey.getKeyId().toHex();
|
||||||
if (!pubKeyId || !privKeyId || pubKeyId !== privKeyId) {
|
if (!pubKeyId || !privKeyId || pubKeyId !== privKeyId) {
|
||||||
resetKeys();
|
resetKeys();
|
||||||
callback(new Error('Key IDs dont match!'));
|
callback(new Error('Key IDs dont match!'));
|
||||||
@ -189,7 +189,7 @@ define(function(require) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
callback(null, {
|
callback(null, {
|
||||||
keyId: this._publicKey.getKeyPacket().getKeyId().toHex().toUpperCase(),
|
keyId: this._publicKey.primaryKey.getKeyId().toHex().toUpperCase(),
|
||||||
privateKeyArmored: this._privateKey.armor(),
|
privateKeyArmored: this._privateKey.armor(),
|
||||||
publicKeyArmored: this._publicKey.armor()
|
publicKeyArmored: this._publicKey.armor()
|
||||||
});
|
});
|
||||||
@ -281,7 +281,7 @@ define(function(require) {
|
|||||||
* You need to check if signatures are both present and valid in the callback!
|
* You need to check if signatures are both present and valid in the callback!
|
||||||
*/
|
*/
|
||||||
PGP.prototype.decrypt = function(ciphertext, publicKeyArmored, callback) {
|
PGP.prototype.decrypt = function(ciphertext, publicKeyArmored, callback) {
|
||||||
var publicKeys, message, signaturesValid, signaturesPresent;
|
var publicKeys, message, signaturesValid;
|
||||||
|
|
||||||
// check keys
|
// check keys
|
||||||
if (!this._privateKey || !publicKeyArmored) {
|
if (!this._privateKey || !publicKeyArmored) {
|
||||||
@ -294,7 +294,7 @@ define(function(require) {
|
|||||||
publicKeys = openpgp.key.readArmored(publicKeyArmored).keys;
|
publicKeys = openpgp.key.readArmored(publicKeyArmored).keys;
|
||||||
message = openpgp.message.readArmored(ciphertext);
|
message = openpgp.message.readArmored(ciphertext);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
callback(new Error('Error decrypting PGP message!'));
|
callback(new Error('Error parsing encrypted PGP message!'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,16 +308,21 @@ define(function(require) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check if signatures are valid
|
// check if signatures are valid
|
||||||
|
if (decrypted.signatures.length > 0) {
|
||||||
signaturesValid = true;
|
signaturesValid = true;
|
||||||
signaturesPresent = !!decrypted.signatures.length;
|
for (var i = 0; i < decrypted.signatures.length; i++) {
|
||||||
decrypted.signatures.forEach(function(sig) {
|
if (decrypted.signatures[i].valid === false) {
|
||||||
if (!sig.valid) {
|
signaturesValid = false; // signature is wrong ... message was tampered with
|
||||||
signaturesValid = false;
|
break;
|
||||||
|
} else if (decrypted.signatures[i].valid === null) {
|
||||||
|
signaturesValid = undefined; // signature not found for the specified public key
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
// return decrypted plaintext
|
// return decrypted plaintext
|
||||||
callback(null, decrypted.text, signaturesPresent, signaturesValid);
|
callback(null, decrypted.text, signaturesValid);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -839,15 +839,11 @@ define(function(require) {
|
|||||||
|
|
||||||
// get the receiver's public key to check the message signature
|
// get the receiver's public key to check the message signature
|
||||||
var encryptedNode = filterBodyParts(message.bodyParts, 'encrypted')[0];
|
var encryptedNode = filterBodyParts(message.bodyParts, 'encrypted')[0];
|
||||||
self._pgp.decrypt(encryptedNode.content, senderPublicKey.publicKey, function(err, decrypted, signaturesPresent, signaturesValid) {
|
self._pgp.decrypt(encryptedNode.content, senderPublicKey.publicKey, function(err, decrypted, signaturesValid) {
|
||||||
if (err || !decrypted) {
|
if (err || !decrypted) {
|
||||||
return showError(err.message || 'An error occurred during the decryption.');
|
return showError(err.message || 'An error occurred during the decryption.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (signaturesPresent && !signaturesValid) {
|
|
||||||
return callback(new Error('Could not verifying the authenticity of this message because PGP signature check failed! This message may have been tampered with!'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the encrypted node contains pgp/inline, we must not parse it
|
// if the encrypted node contains pgp/inline, we must not parse it
|
||||||
// with the mailreader as it is not well-formed MIME
|
// with the mailreader as it is not well-formed MIME
|
||||||
if (encryptedNode._isPgpInline) {
|
if (encryptedNode._isPgpInline) {
|
||||||
@ -881,7 +877,7 @@ define(function(require) {
|
|||||||
|
|
||||||
// if the decryption worked and signatures are present, everything's fine.
|
// if the decryption worked and signatures are present, everything's fine.
|
||||||
// no error is thrown if signatures are not present
|
// no error is thrown if signatures are not present
|
||||||
message.signed = signaturesPresent;
|
message.signed = signaturesValid;
|
||||||
message.decrypted = true;
|
message.decrypted = true;
|
||||||
|
|
||||||
// we're done here!
|
// we're done here!
|
||||||
|
@ -377,8 +377,8 @@ define(function(require) {
|
|||||||
|
|
||||||
// decrypt the session key
|
// decrypt the session key
|
||||||
var ct = regSessionKey.encryptedRegSessionKey;
|
var ct = regSessionKey.encryptedRegSessionKey;
|
||||||
self._pgp.decrypt(ct, serverPubkey.publicKey, function(err, decrypedSessionKey, signaturesPresent, signaturesValid) {
|
self._pgp.decrypt(ct, serverPubkey.publicKey, function(err, decrypedSessionKey, signaturesValid) {
|
||||||
if (err || !(/*signaturesPresent &&*/ signaturesValid)) {
|
if (err || !signaturesValid) {
|
||||||
return callback(err || new Error('Verifying PGP signature failed!'));
|
return callback(err || new Error('Verifying PGP signature failed!'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -464,15 +464,15 @@ define(function(require) {
|
|||||||
|
|
||||||
// decrypt the session key
|
// decrypt the session key
|
||||||
var ct1 = authSessionKey.encryptedAuthSessionKey;
|
var ct1 = authSessionKey.encryptedAuthSessionKey;
|
||||||
self._pgp.decrypt(ct1, serverPubkey.publicKey, function(err, decryptedSessionKey, signaturesPresent, signaturesValid) {
|
self._pgp.decrypt(ct1, serverPubkey.publicKey, function(err, decryptedSessionKey, signaturesValid) {
|
||||||
if (err || !(/*signaturesPresent &&*/ signaturesValid)) {
|
if (err || !signaturesValid) {
|
||||||
return callback(err || new Error('Verifying PGP signature failed!'));
|
return callback(err || new Error('Verifying PGP signature failed!'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// decrypt the challenge
|
// decrypt the challenge
|
||||||
var ct2 = authSessionKey.encryptedChallenge;
|
var ct2 = authSessionKey.encryptedChallenge;
|
||||||
self._pgp.decrypt(ct2, serverPubkey.publicKey, function(err, decryptedChallenge, signaturesPresent, signaturesValid) {
|
self._pgp.decrypt(ct2, serverPubkey.publicKey, function(err, decryptedChallenge, signaturesValid) {
|
||||||
if (err || !(/*signaturesPresent &&*/ signaturesValid)) {
|
if (err || !signaturesValid) {
|
||||||
return callback(err || new Error('Verifying PGP signature failed!'));
|
return callback(err || new Error('Verifying PGP signature failed!'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
16891
src/lib/openpgp/openpgp.js
Normal file
16891
src/lib/openpgp/openpgp.js
Normal file
File diff suppressed because it is too large
Load Diff
7
src/lib/openpgp/openpgp.min.js
vendored
7
src/lib/openpgp/openpgp.min.js
vendored
File diff suppressed because one or more lines are too long
172
src/lib/openpgp/openpgp.worker.js
Normal file
172
src/lib/openpgp/openpgp.worker.js
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
;(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||||||
|
// GPG4Browsers - An OpenPGP implementation in javascript
|
||||||
|
// Copyright (C) 2011 Recurity Labs GmbH
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 2.1 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
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
window = {}; // to make UMD bundles work
|
||||||
|
|
||||||
|
importScripts('openpgp.js');
|
||||||
|
|
||||||
|
var MIN_SIZE_RANDOM_BUFFER = 40000;
|
||||||
|
var MAX_SIZE_RANDOM_BUFFER = 60000;
|
||||||
|
|
||||||
|
window.openpgp.crypto.random.randomBuffer.init(MAX_SIZE_RANDOM_BUFFER);
|
||||||
|
|
||||||
|
onmessage = function (event) {
|
||||||
|
var data = null,
|
||||||
|
err = null,
|
||||||
|
msg = event.data,
|
||||||
|
correct = false;
|
||||||
|
switch (msg.event) {
|
||||||
|
case 'seed-random':
|
||||||
|
if (!(msg.buf instanceof Uint8Array)) {
|
||||||
|
msg.buf = new Uint8Array(msg.buf);
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
response({event: 'method-return', data: data, err: err});
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
response({event: 'method-return', data: data, err: err});
|
||||||
|
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});
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
response({event: 'method-return', data: data, err: err});
|
||||||
|
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});
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
response({event: 'method-return', data: data, err: err});
|
||||||
|
break;
|
||||||
|
case 'generate-key-pair':
|
||||||
|
try {
|
||||||
|
data = window.openpgp.generateKeyPair(msg.options);
|
||||||
|
data.key = data.key.toPacketlist();
|
||||||
|
} catch (e) {
|
||||||
|
err = e.message;
|
||||||
|
}
|
||||||
|
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.');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function response(event) {
|
||||||
|
if (window.openpgp.crypto.random.randomBuffer.size < MIN_SIZE_RANDOM_BUFFER) {
|
||||||
|
postMessage({event: 'request-seed'});
|
||||||
|
}
|
||||||
|
postMessage(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
function packetlistCloneToKey(packetlistClone) {
|
||||||
|
var packetlist = window.openpgp.packet.List.fromStructuredClone(packetlistClone);
|
||||||
|
return new window.openpgp.key.Key(packetlist);
|
||||||
|
}
|
||||||
|
|
||||||
|
function packetlistCloneToMessage(packetlistClone) {
|
||||||
|
var packetlist = window.openpgp.packet.List.fromStructuredClone(packetlistClone);
|
||||||
|
return new window.openpgp.message.Message(packetlist);
|
||||||
|
}
|
||||||
|
},{}]},{},[1])
|
||||||
|
;
|
1
src/lib/openpgp/openpgp.worker.min.js
vendored
1
src/lib/openpgp/openpgp.worker.min.js
vendored
@ -1 +0,0 @@
|
|||||||
/*! OpenPGPjs.org this is LGPL licensed code, see LICENSE/our website for more information.- v0.6.0 - 2014-05-09 */!function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(){function a(a){window.openpgp.crypto.random.randomBuffer.size<d&&postMessage({event:"request-seed"}),postMessage(a)}function b(a){var b=window.openpgp.packet.List.fromStructuredClone(a);return new window.openpgp.key.Key(b)}function c(a){var b=window.openpgp.packet.List.fromStructuredClone(a);return new window.openpgp.message.Message(b)}window={},importScripts("openpgp.min.js");var d=4e4,e=6e4;window.openpgp.crypto.random.randomBuffer.init(e),onmessage=function(d){var e=null,f=null,g=d.data,h=!1;switch(g.event){case"seed-random":g.buf instanceof Uint8Array||(g.buf=new Uint8Array(g.buf)),window.openpgp.crypto.random.randomBuffer.set(g.buf);break;case"encrypt-message":try{g.keys=g.keys.map(b),e=window.openpgp.encryptMessage(g.keys,g.text)}catch(i){f=i.message}a({event:"method-return",data:e,err:f});break;case"sign-and-encrypt-message":try{g.publicKeys=g.publicKeys.map(b),g.privateKey=b(g.privateKey),e=window.openpgp.signAndEncryptMessage(g.publicKeys,g.privateKey,g.text)}catch(i){f=i.message}a({event:"method-return",data:e,err:f});break;case"decrypt-message":try{g.privateKey=b(g.privateKey),g.message=c(g.message.packets),e=window.openpgp.decryptMessage(g.privateKey,g.message)}catch(i){f=i.message}a({event:"method-return",data:e,err:f});break;case"decrypt-and-verify-message":try{g.privateKey=b(g.privateKey),g.publicKeys=g.publicKeys.map(b),g.message=c(g.message.packets),e=window.openpgp.decryptAndVerifyMessage(g.privateKey,g.publicKeys,g.message)}catch(i){f=i.message}a({event:"method-return",data:e,err:f});break;case"sign-clear-message":try{g.privateKeys=g.privateKeys.map(b),e=window.openpgp.signClearMessage(g.privateKeys,g.text)}catch(i){f=i.message}a({event:"method-return",data:e,err:f});break;case"verify-clear-signed-message":try{g.publicKeys=g.publicKeys.map(b);var j=window.openpgp.packet.List.fromStructuredClone(g.message.packets);g.message=new window.openpgp.cleartext.CleartextMessage(g.message.text,j),e=window.openpgp.verifyClearSignedMessage(g.publicKeys,g.message)}catch(i){f=i.message}a({event:"method-return",data:e,err:f});break;case"generate-key-pair":try{e=window.openpgp.generateKeyPair(g.options),e.key=e.key.toPacketlist()}catch(i){f=i.message}a({event:"method-return",data:e,err:f});break;case"decrypt-key":try{g.privateKey=b(g.privateKey),h=g.privateKey.decrypt(g.password),h?e=g.privateKey.toPacketlist():f="Wrong password"}catch(i){f=i.message}a({event:"method-return",data:e,err:f});break;case"decrypt-key-packet":try{g.privateKey=b(g.privateKey),g.keyIds=g.keyIds.map(window.openpgp.Keyid.fromClone),h=g.privateKey.decryptKeyPacket(g.keyIds,g.password),h?e=g.privateKey.toPacketlist():f="Wrong password"}catch(i){f=i.message}a({event:"method-return",data:e,err:f});break;default:throw new Error("Unknown Worker Event.")}}},{}]},{},[1]);
|
|
@ -18,7 +18,7 @@
|
|||||||
uuid: 'uuid/uuid',
|
uuid: 'uuid/uuid',
|
||||||
forge: 'forge/forge.min',
|
forge: 'forge/forge.min',
|
||||||
punycode: 'punycode.min',
|
punycode: 'punycode.min',
|
||||||
openpgp: 'openpgp/openpgp.min',
|
openpgp: 'openpgp/openpgp',
|
||||||
fastclick: 'fastclick/fastclick'
|
fastclick: 'fastclick/fastclick'
|
||||||
},
|
},
|
||||||
shim: {
|
shim: {
|
||||||
|
@ -461,7 +461,7 @@ define(function(require) {
|
|||||||
}, function(err) {
|
}, function(err) {
|
||||||
expect(err).to.not.exist;
|
expect(err).to.not.exist;
|
||||||
expect(message.encrypted).to.be.true;
|
expect(message.encrypted).to.be.true;
|
||||||
expect(message.signed).to.be.false;
|
expect(message.signed).to.be.undefined;
|
||||||
expect(message.attachments.length).to.equal(1);
|
expect(message.attachments.length).to.equal(1);
|
||||||
expect(message.body).to.equal('test16');
|
expect(message.body).to.equal('test16');
|
||||||
done();
|
done();
|
||||||
@ -527,7 +527,7 @@ define(function(require) {
|
|||||||
}, function(err) {
|
}, function(err) {
|
||||||
expect(err).to.not.exist;
|
expect(err).to.not.exist;
|
||||||
expect(message.encrypted).to.be.true;
|
expect(message.encrypted).to.be.true;
|
||||||
expect(message.signed).to.be.false;
|
expect(message.signed).to.be.undefined;
|
||||||
expect(message.attachments.length).to.equal(0);
|
expect(message.attachments.length).to.equal(0);
|
||||||
expect(message.body).to.equal('test13');
|
expect(message.body).to.equal('test13');
|
||||||
done();
|
done();
|
||||||
@ -593,7 +593,7 @@ define(function(require) {
|
|||||||
}, function(err) {
|
}, function(err) {
|
||||||
expect(err).to.not.exist;
|
expect(err).to.not.exist;
|
||||||
expect(message.encrypted).to.be.true;
|
expect(message.encrypted).to.be.true;
|
||||||
expect(message.signed).to.be.false;
|
expect(message.signed).to.be.undefined;
|
||||||
expect(message.attachments.length).to.equal(1);
|
expect(message.attachments.length).to.equal(1);
|
||||||
expect(message.body).to.equal('test10');
|
expect(message.body).to.equal('test10');
|
||||||
done();
|
done();
|
||||||
|
@ -1239,7 +1239,7 @@ define(function(require) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
keychainStub.getReceiverPublicKey.withArgs(message.from[0].address).yieldsAsync(null, mockKeyPair.publicKey);
|
keychainStub.getReceiverPublicKey.withArgs(message.from[0].address).yieldsAsync(null, mockKeyPair.publicKey);
|
||||||
pgpStub.decrypt.withArgs(ct, mockKeyPair.publicKey.publicKey).yieldsAsync(null, pt);
|
pgpStub.decrypt.withArgs(ct, mockKeyPair.publicKey.publicKey).yieldsAsync(null, pt, true);
|
||||||
parseStub.withArgs({
|
parseStub.withArgs({
|
||||||
bodyParts: [{
|
bodyParts: [{
|
||||||
type: 'encrypted',
|
type: 'encrypted',
|
||||||
@ -1291,7 +1291,7 @@ define(function(require) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
keychainStub.getReceiverPublicKey.withArgs(message.from[0].address).yieldsAsync(null, mockKeyPair.publicKey);
|
keychainStub.getReceiverPublicKey.withArgs(message.from[0].address).yieldsAsync(null, mockKeyPair.publicKey);
|
||||||
pgpStub.decrypt.withArgs(ct, mockKeyPair.publicKey.publicKey).yieldsAsync(null, pt);
|
pgpStub.decrypt.withArgs(ct, mockKeyPair.publicKey.publicKey).yieldsAsync(null, pt, true);
|
||||||
|
|
||||||
dao.decryptBody({
|
dao.decryptBody({
|
||||||
message: message
|
message: message
|
||||||
|
@ -13,7 +13,7 @@ define(function(require) {
|
|||||||
keySize = 512,
|
keySize = 512,
|
||||||
keyId = 'F6F60E9B42CDFF4C',
|
keyId = 'F6F60E9B42CDFF4C',
|
||||||
pubkey = '-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n' +
|
pubkey = '-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n' +
|
||||||
'Version: OpenPGP.js v0.6.0\r\n' +
|
'Version: OpenPGP.js v0.6.5\r\n' +
|
||||||
'Comment: http://openpgpjs.org\r\n' +
|
'Comment: http://openpgpjs.org\r\n' +
|
||||||
'\r\n' +
|
'\r\n' +
|
||||||
'xk0EUlhMvAEB/2MZtCUOAYvyLFjDp3OBMGn3Ev8FwjzyPbIF0JUw+L7y2XR5\r\n' +
|
'xk0EUlhMvAEB/2MZtCUOAYvyLFjDp3OBMGn3Ev8FwjzyPbIF0JUw+L7y2XR5\r\n' +
|
||||||
@ -24,7 +24,7 @@ define(function(require) {
|
|||||||
'=6XMW\r\n' +
|
'=6XMW\r\n' +
|
||||||
'-----END PGP PUBLIC KEY BLOCK-----\r\n\r\n',
|
'-----END PGP PUBLIC KEY BLOCK-----\r\n\r\n',
|
||||||
privkey = '-----BEGIN PGP PRIVATE KEY BLOCK-----\r\n' +
|
privkey = '-----BEGIN PGP PRIVATE KEY BLOCK-----\r\n' +
|
||||||
'Version: OpenPGP.js v0.6.0\r\n' +
|
'Version: OpenPGP.js v0.6.5\r\n' +
|
||||||
'Comment: http://openpgpjs.org\r\n' +
|
'Comment: http://openpgpjs.org\r\n' +
|
||||||
'\r\n' +
|
'\r\n' +
|
||||||
'xcBeBFJYTLwBAf9jGbQlDgGL8ixYw6dzgTBp9xL/BcI88j2yBdCVMPi+8tl0\r\n' +
|
'xcBeBFJYTLwBAf9jGbQlDgGL8ixYw6dzgTBp9xL/BcI88j2yBdCVMPi+8tl0\r\n' +
|
||||||
@ -69,7 +69,7 @@ define(function(require) {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('should work', function(done) {
|
it('should work with passphrase', function(done) {
|
||||||
pgp.generateKeys({
|
pgp.generateKeys({
|
||||||
emailAddress: user,
|
emailAddress: user,
|
||||||
keySize: keySize,
|
keySize: keySize,
|
||||||
@ -82,6 +82,19 @@ define(function(require) {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it('should work without passphrase', function(done) {
|
||||||
|
pgp.generateKeys({
|
||||||
|
emailAddress: user,
|
||||||
|
keySize: keySize,
|
||||||
|
passphrase: ''
|
||||||
|
}, function(err, keys) {
|
||||||
|
expect(err).to.not.exist;
|
||||||
|
expect(keys.keyId).to.exist;
|
||||||
|
expect(keys.privateKeyArmored).to.exist;
|
||||||
|
expect(keys.publicKeyArmored).to.exist;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Import/Export key pair', function() {
|
describe('Import/Export key pair', function() {
|
||||||
@ -121,7 +134,7 @@ define(function(require) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('Change passphrase of private key', function() {
|
describe('Change passphrase of private key', function() {
|
||||||
it('should work', function(done) {
|
it('should work with new passphrase', function(done) {
|
||||||
pgp.changePassphrase({
|
pgp.changePassphrase({
|
||||||
privateKeyArmored: privkey,
|
privateKeyArmored: privkey,
|
||||||
oldPassphrase: passphrase,
|
oldPassphrase: passphrase,
|
||||||
@ -140,7 +153,25 @@ define(function(require) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it('should work with empty passphrase', function(done) {
|
||||||
|
pgp.changePassphrase({
|
||||||
|
privateKeyArmored: privkey,
|
||||||
|
oldPassphrase: passphrase,
|
||||||
|
newPassphrase: undefined
|
||||||
|
}, function(err, reEncryptedKey) {
|
||||||
|
expect(err).to.not.exist;
|
||||||
|
expect(reEncryptedKey).to.exist;
|
||||||
|
|
||||||
|
pgp.importKeys({
|
||||||
|
passphrase: undefined,
|
||||||
|
privateKeyArmored: reEncryptedKey,
|
||||||
|
publicKeyArmored: pubkey
|
||||||
|
}, function(err) {
|
||||||
|
expect(err).to.not.exist;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
it('should fail when passphrases are equal', function(done) {
|
it('should fail when passphrases are equal', function(done) {
|
||||||
pgp.changePassphrase({
|
pgp.changePassphrase({
|
||||||
privateKeyArmored: privkey,
|
privateKeyArmored: privkey,
|
||||||
@ -152,7 +183,6 @@ define(function(require) {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when old passphrase is incorrect', function(done) {
|
it('should fail when old passphrase is incorrect', function(done) {
|
||||||
pgp.changePassphrase({
|
pgp.changePassphrase({
|
||||||
privateKeyArmored: privkey,
|
privateKeyArmored: privkey,
|
||||||
@ -275,9 +305,21 @@ define(function(require) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should work', function(done) {
|
it('should work', function(done) {
|
||||||
pgp.decrypt(ciphertext, pubkey, function(err, pt) {
|
pgp.decrypt(ciphertext, pubkey, function(err, pt, signValid) {
|
||||||
expect(err).to.not.exist;
|
expect(err).to.not.exist;
|
||||||
expect(pt).to.equal(message);
|
expect(pt).to.equal(message);
|
||||||
|
expect(signValid).to.be.true;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should decrypt but signValid should be undefined for wrong public key', function(done) {
|
||||||
|
var wrongPubkey = '-----BEGIN PGP PUBLIC KEY BLOCK-----\r\nVersion: OpenPGP.js v.1.20131116\r\nComment: Whiteout Mail - http://whiteout.io\r\n\r\nxsBNBFKODs4BB/9iOF4THsjQMY+WEpT7ShgKxj4bHzRRaQkqczS4nZvP0U3g\r\nqeqCnbpagyeKXA+bhWFQW4GmXtgAoeD5PXs6AZYrw3tWNxLKu2Oe6Tp9K/XI\r\nxTMQ2wl4qZKDXHvuPsJ7cmgaWqpPyXtxA4zHHS3WrkI/6VzHAcI/y6x4szSB\r\nKgSuhI3hjh3s7TybUC1U6AfoQGx/S7e3WwlCOrK8GTClirN/2mCPRC5wuIft\r\nnkoMfA6jK8d2OPrJ63shy5cgwHOjQg/xuk46dNS7tkvGmbaa+X0PgqSKB+Hf\r\nYPPNS/ylg911DH9qa8BqYU2QpNh9jUKXSF+HbaOM+plWkCSAL7czV+R3ABEB\r\nAAHNLVdoaXRlb3V0IFVzZXIgPHNhZmV3aXRobWUudGVzdHVzZXJAZ21haWwu\r\nY29tPsLAXAQQAQgAEAUCUo4O2gkQ1/uT/N+/wjwAAN2cB/9gFRmAfvEQ2qz+\r\nWubmT2EsSSnjPMxzG4uyykFoa+TaZCWo2Xa2tQghmU103kEkQb1OEjRjpgwJ\r\nYX9Kghnl8DByM686L5AXnRyHP78qRJCLXSXl0AGicboUDp5sovaa4rswQceH\r\nvcdWgZ/mgHTRoiQeJddy9k+H6MPFiyFaVcFwegVsmpc+dCcC8yT+qh8ZIbyG\r\nRJU60PmKKN7LUusP+8DbSv39zCGJCBlVVKyA4MzdF5uM+sqTdXbKzOrT5DGd\r\nCZaox4s+w16Sq1rHzZKFWfQPfKLDB9pyA0ufCVRA3AF6BUi7G3ZqhZiHNhMP\r\nNvE45V/hS1PbZcfPVoUjE2qc1Ix1\r\n=7Wpe\r\n-----END PGP PUBLIC KEY BLOCK-----';
|
||||||
|
|
||||||
|
pgp.decrypt(ciphertext, wrongPubkey, function(err, pt, signValid) {
|
||||||
|
expect(err).to.not.exist;
|
||||||
|
expect(pt).to.equal(message);
|
||||||
|
expect(signValid).to.be.undefined;
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user