Refactor complete public api to use promises
This commit is contained in:
parent
0ac58356b5
commit
7f2573c77d
39
.jshintrc
Normal file
39
.jshintrc
Normal file
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"indent": 2,
|
||||
"strict": true,
|
||||
"globalstrict": true,
|
||||
"node": true,
|
||||
"browser": true,
|
||||
"nonew": true,
|
||||
"curly": true,
|
||||
"eqeqeq": true,
|
||||
"immed": true,
|
||||
"newcap": true,
|
||||
"regexp": true,
|
||||
"evil": true,
|
||||
"eqnull": true,
|
||||
"expr": true,
|
||||
"trailing": true,
|
||||
"undef": true,
|
||||
"unused": true,
|
||||
|
||||
"predef": [
|
||||
"console",
|
||||
"Promise",
|
||||
"importScripts",
|
||||
"process",
|
||||
"Event",
|
||||
"self",
|
||||
"describe",
|
||||
"it",
|
||||
"sinon",
|
||||
"mocha",
|
||||
"before",
|
||||
"beforeEach",
|
||||
"after",
|
||||
"afterEach"
|
||||
],
|
||||
|
||||
"globals": {
|
||||
}
|
||||
}
|
|
@ -38,7 +38,7 @@ module.exports = function(grunt) {
|
|||
'test/lib/unittests-bundle.js': [ './test/unittests.js' ]
|
||||
},
|
||||
options: {
|
||||
external: [ 'openpgp', 'crypto', 'node-localstorage' ]
|
||||
external: [ 'openpgp', 'crypto', 'node-localstorage', 'es6-promise']
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -116,7 +116,7 @@ module.exports = function(grunt) {
|
|||
expand: true,
|
||||
flatten: true,
|
||||
cwd: 'node_modules/',
|
||||
src: ['mocha/mocha.css', 'mocha/mocha.js', 'chai/chai.js'],
|
||||
src: ['mocha/mocha.css', 'mocha/mocha.js', 'chai/chai.js', 'es6-promise/dist/promise*.js'],
|
||||
dest: 'test/lib/'
|
||||
}
|
||||
},
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
"devDependencies": {
|
||||
"browserify": "~2.35",
|
||||
"chai": "~1.8.1",
|
||||
"es6-promise": "1.0.0",
|
||||
"grunt": "~0.4.2",
|
||||
"grunt-browserify": "~1.2.11",
|
||||
"grunt-cli": "~0.1.13",
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
// 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 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
|
||||
// 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
|
||||
|
@ -23,6 +23,8 @@
|
|||
* @module cleartext
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var config = require('./config'),
|
||||
packet = require('./packet'),
|
||||
enums = require('./enums.js'),
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
'use strict';
|
||||
|
||||
/**
|
||||
* @module enums
|
||||
*/
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = require('./openpgp.js');
|
||||
/**
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
* @module key
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var packet = require('./packet'),
|
||||
enums = require('./enums.js'),
|
||||
armor = require('./encoding/armor.js'),
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
// 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 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
|
||||
// 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
|
||||
|
@ -24,6 +24,8 @@
|
|||
* @module message
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var packet = require('./packet'),
|
||||
enums = require('./enums.js'),
|
||||
armor = require('./encoding/armor.js'),
|
||||
|
@ -83,7 +85,7 @@ Message.prototype.getSigningKeyIds = function() {
|
|||
|
||||
/**
|
||||
* Decrypt the message
|
||||
* @param {module:key~Key} privateKey private key with decrypted secret data
|
||||
* @param {module:key~Key} privateKey private key with decrypted secret data
|
||||
* @return {Array<module:message~Message>} new message with decrypted content
|
||||
*/
|
||||
Message.prototype.decrypt = function(privateKey) {
|
||||
|
@ -186,7 +188,7 @@ Message.prototype.sign = function(privateKeys) {
|
|||
|
||||
var literalDataPacket = this.packets.findPacket(enums.packet.literal);
|
||||
if (!literalDataPacket) throw new Error('No literal data packet to sign.');
|
||||
|
||||
|
||||
var literalFormat = enums.write(enums.literal, literalDataPacket.format);
|
||||
var signatureType = literalFormat == enums.literal.binary ?
|
||||
enums.signature.binary : enums.signature.text;
|
||||
|
@ -206,7 +208,7 @@ Message.prototype.sign = function(privateKeys) {
|
|||
}
|
||||
|
||||
packetlist.push(literalDataPacket);
|
||||
|
||||
|
||||
for (i = privateKeys.length - 1; i >= 0; i--) {
|
||||
var signaturePacket = new packet.Signature();
|
||||
signaturePacket.signatureType = signatureType;
|
||||
|
|
117
src/openpgp.js
117
src/openpgp.js
|
@ -31,10 +31,10 @@
|
|||
* @module openpgp
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var armor = require('./encoding/armor.js'),
|
||||
packet = require('./packet'),
|
||||
enums = require('./enums.js'),
|
||||
config = require('./config'),
|
||||
message = require('./message.js'),
|
||||
cleartext = require('./cleartext.js'),
|
||||
key = require('./key.js'),
|
||||
|
@ -55,18 +55,16 @@ function initWorker(path) {
|
|||
* 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 (optional) callback(error, result) for async style
|
||||
* @return {String} encrypted ASCII armored message
|
||||
* @static
|
||||
*/
|
||||
function encryptMessage(keys, text, callback) {
|
||||
function encryptMessage(keys, text) {
|
||||
if (!keys.length) {
|
||||
keys = [keys];
|
||||
}
|
||||
|
||||
if (useWorker(callback)) {
|
||||
asyncProxy.encryptMessage(keys, text, callback);
|
||||
return;
|
||||
if (useWorker()) {
|
||||
return asyncProxy.encryptMessage(keys, text);
|
||||
}
|
||||
|
||||
return execute(function() {
|
||||
|
@ -75,7 +73,7 @@ function encryptMessage(keys, text, callback) {
|
|||
msg = msg.encrypt(keys);
|
||||
armored = armor.encode(enums.armor.message, msg.packets.write());
|
||||
return armored;
|
||||
}, callback);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -83,18 +81,16 @@ function encryptMessage(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 (optional) callback(error, result) for async style
|
||||
* @return {String} encrypted ASCII armored message
|
||||
* @static
|
||||
*/
|
||||
function signAndEncryptMessage(publicKeys, privateKey, text, callback) {
|
||||
function signAndEncryptMessage(publicKeys, privateKey, text) {
|
||||
if (!publicKeys.length) {
|
||||
publicKeys = [publicKeys];
|
||||
}
|
||||
|
||||
if (useWorker(callback)) {
|
||||
asyncProxy.signAndEncryptMessage(publicKeys, privateKey, text, callback);
|
||||
return;
|
||||
if (useWorker()) {
|
||||
return asyncProxy.signAndEncryptMessage(publicKeys, privateKey, text);
|
||||
}
|
||||
|
||||
return execute(function() {
|
||||
|
@ -104,28 +100,26 @@ function signAndEncryptMessage(publicKeys, privateKey, text, callback) {
|
|||
msg = msg.encrypt(publicKeys);
|
||||
armored = armor.encode(enums.armor.message, msg.packets.write());
|
||||
return armored;
|
||||
}, callback);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts message
|
||||
* @param {module:key~Key} privateKey private key with decrypted secret key data
|
||||
* @param {module:message~Message} msg the message object with the encrypted data
|
||||
* @param {function} callback (optional) callback(error, result) for async style
|
||||
* @return {(String|null)} decrypted message as as native JavaScript string
|
||||
* or null if no literal data found
|
||||
* @static
|
||||
*/
|
||||
function decryptMessage(privateKey, msg, callback) {
|
||||
if (useWorker(callback)) {
|
||||
asyncProxy.decryptMessage(privateKey, msg, callback);
|
||||
return;
|
||||
function decryptMessage(privateKey, msg) {
|
||||
if (useWorker()) {
|
||||
return asyncProxy.decryptMessage(privateKey, msg);
|
||||
}
|
||||
|
||||
return execute(function() {
|
||||
msg = msg.decrypt(privateKey);
|
||||
return msg.getText();
|
||||
}, callback);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -133,20 +127,18 @@ function decryptMessage(privateKey, msg, 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} msg the message object with signed and encrypted data
|
||||
* @param {function} callback (optional) callback(error, result) for async style
|
||||
* @return {{text: String, signatures: Array<{keyid: module:type/keyid, valid: Boolean}>}}
|
||||
* decrypted message as as native JavaScript string
|
||||
* with verified signatures or null if no literal data found
|
||||
* @static
|
||||
*/
|
||||
function decryptAndVerifyMessage(privateKey, publicKeys, msg, callback) {
|
||||
function decryptAndVerifyMessage(privateKey, publicKeys, msg) {
|
||||
if (!publicKeys.length) {
|
||||
publicKeys = [publicKeys];
|
||||
}
|
||||
|
||||
if (useWorker(callback)) {
|
||||
asyncProxy.decryptAndVerifyMessage(privateKey, publicKeys, msg, callback);
|
||||
return;
|
||||
if (useWorker()) {
|
||||
return asyncProxy.decryptAndVerifyMessage(privateKey, publicKeys, msg);
|
||||
}
|
||||
|
||||
return execute(function() {
|
||||
|
@ -158,51 +150,47 @@ function decryptAndVerifyMessage(privateKey, publicKeys, msg, callback) {
|
|||
return result;
|
||||
}
|
||||
return null;
|
||||
}, callback);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 (optional) callback(error, result) for async style
|
||||
* @return {String} ASCII armored message
|
||||
* @static
|
||||
*/
|
||||
function signClearMessage(privateKeys, text, callback) {
|
||||
function signClearMessage(privateKeys, text) {
|
||||
if (!privateKeys.length) {
|
||||
privateKeys = [privateKeys];
|
||||
}
|
||||
|
||||
if (useWorker(callback)) {
|
||||
asyncProxy.signClearMessage(privateKeys, text, callback);
|
||||
return;
|
||||
if (useWorker()) {
|
||||
return asyncProxy.signClearMessage(privateKeys, text);
|
||||
}
|
||||
|
||||
return execute(function() {
|
||||
var cleartextMessage = new cleartext.CleartextMessage(text);
|
||||
cleartextMessage.sign(privateKeys);
|
||||
return cleartextMessage.armor();
|
||||
}, 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} msg cleartext message object with signatures
|
||||
* @param {function} callback (optional) callback(error, result) for async style
|
||||
* @return {{text: String, signatures: Array<{keyid: module:type/keyid, valid: Boolean}>}}
|
||||
* cleartext with status of verified signatures
|
||||
* @static
|
||||
*/
|
||||
function verifyClearSignedMessage(publicKeys, msg, callback) {
|
||||
function verifyClearSignedMessage(publicKeys, msg) {
|
||||
if (!publicKeys.length) {
|
||||
publicKeys = [publicKeys];
|
||||
}
|
||||
|
||||
if (useWorker(callback)) {
|
||||
asyncProxy.verifyClearSignedMessage(publicKeys, msg, callback);
|
||||
return;
|
||||
if (useWorker()) {
|
||||
return asyncProxy.verifyClearSignedMessage(publicKeys, msg);
|
||||
}
|
||||
|
||||
return execute(function() {
|
||||
|
@ -213,7 +201,7 @@ function verifyClearSignedMessage(publicKeys, msg, callback) {
|
|||
result.text = msg.getText();
|
||||
result.signatures = msg.verify(publicKeys);
|
||||
return result;
|
||||
}, callback);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -225,15 +213,13 @@ function verifyClearSignedMessage(publicKeys, msg, callback) {
|
|||
* @param {String} options.userId assumes already in form of "User Name <username@email.com>"
|
||||
* @param {String} options.passphrase The passphrase used to encrypt the resulting private key
|
||||
* @param {Boolean} [options.unlocked=false] The secret part of the generated key is unlocked
|
||||
* @param {function} callback(error, result) The required callback
|
||||
* @return {Object} {key: module:key~Key, privateKeyArmored: String, publicKeyArmored: String}
|
||||
* @static
|
||||
*/
|
||||
function generateKeyPair(options) {
|
||||
// use web worker if web crypto apis are not supported
|
||||
if (!util.getWebCrypto() && useWorker()) {
|
||||
asyncProxy.generateKeyPair(options);
|
||||
return;
|
||||
return asyncProxy.generateKeyPair(options);
|
||||
}
|
||||
|
||||
return key.generate(options).then(function(newKey) {
|
||||
|
@ -243,10 +229,7 @@ function generateKeyPair(options) {
|
|||
result.publicKeyArmored = newKey.toPublic().armor();
|
||||
return result;
|
||||
|
||||
}).catch(function(err) {
|
||||
console.error(err.stack);
|
||||
throw new Error('Error generating keypair!');
|
||||
});
|
||||
}).catch(onError.bind(null, 'Error generating keypair!'));
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -270,28 +253,36 @@ function useWorker(callback) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Command pattern that handles async calls gracefully
|
||||
* Command pattern that wraps synchronous code into a promise
|
||||
* @param {function} cmd The synchronous function with a return value
|
||||
* to be wrapped in a promise
|
||||
* @param {String} errMsg A human readable error Message
|
||||
* @return {Promise} The promise wrapped around cmd
|
||||
*/
|
||||
function execute(cmd, callback) {
|
||||
var result;
|
||||
function execute(cmd, errMsg) {
|
||||
// wrap the sync cmd in a promise
|
||||
var promise = new Promise(function(resolve) {
|
||||
var result = cmd();
|
||||
resolve(result);
|
||||
});
|
||||
|
||||
try {
|
||||
result = cmd();
|
||||
} catch (err) {
|
||||
if (callback) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
// handler error globally
|
||||
promise.catch(onError.bind(null, errMsg));
|
||||
|
||||
throw err;
|
||||
}
|
||||
return promise;
|
||||
}
|
||||
|
||||
if (callback) {
|
||||
callback(null, result);
|
||||
return;
|
||||
}
|
||||
|
||||
return result;
|
||||
/**
|
||||
* Global error handler that logs the stack trace and
|
||||
* rethrows a high lvl error message
|
||||
* @param {String} message A human readable high level error Message
|
||||
* @param {Error} error The internal error that caused the failure
|
||||
*/
|
||||
function onError(message, error) {
|
||||
// log the stack trace
|
||||
console.error(error.stack);
|
||||
// rethrow new high level error for api users
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
exports.initWorker = initWorker;
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
* @module util
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var config = require('./config');
|
||||
|
||||
module.exports = {
|
||||
|
|
|
@ -10,16 +10,16 @@ describe('Basic', function() {
|
|||
describe("Key generation/encryption/decryption", function() {
|
||||
var testHelper = function(passphrase, userid, message, done) {
|
||||
var opt = {numBits: 512, userId: userid, passphrase: passphrase};
|
||||
openpgp.generateKeyPair(opt, function(err, key) {
|
||||
expect(err).to.not.exist;
|
||||
var privKey;
|
||||
var pubKey;
|
||||
|
||||
openpgp.generateKeyPair(opt).then(function(key) {
|
||||
|
||||
expect(key).to.exist;
|
||||
expect(key.key).to.exist;
|
||||
expect(key.privateKeyArmored).to.exist;
|
||||
expect(key.publicKeyArmored).to.exist;
|
||||
|
||||
var info = '\npassphrase: ' + passphrase + '\n' + 'userid: ' + userid + '\n' + 'message: ' + message;
|
||||
|
||||
var privKeys = openpgp.key.readArmored(key.privateKeyArmored);
|
||||
var publicKeys = openpgp.key.readArmored(key.publicKeyArmored);
|
||||
|
||||
|
@ -27,29 +27,28 @@ describe('Basic', function() {
|
|||
expect(privKeys.err).to.not.exist;
|
||||
expect(privKeys.keys).to.have.length(1);
|
||||
|
||||
var privKey = privKeys.keys[0];
|
||||
var pubKey = publicKeys.keys[0];
|
||||
privKey = privKeys.keys[0];
|
||||
pubKey = publicKeys.keys[0];
|
||||
|
||||
expect(privKey).to.exist;
|
||||
expect(pubKey).to.exist;
|
||||
|
||||
var success = privKey.decrypt(passphrase);
|
||||
|
||||
expect(success).to.be.true;
|
||||
|
||||
var encrypted = openpgp.signAndEncryptMessage([pubKey], privKey, message);
|
||||
return openpgp.signAndEncryptMessage([pubKey], privKey, message);
|
||||
|
||||
}).then(function(encrypted) {
|
||||
|
||||
expect(encrypted).to.exist;
|
||||
|
||||
var msg = openpgp.message.readArmored(encrypted);
|
||||
|
||||
expect(msg).to.exist;
|
||||
|
||||
var keyids = msg.getEncryptionKeyIds();
|
||||
|
||||
expect(keyids).to.exist;
|
||||
|
||||
var decrypted = openpgp.decryptAndVerifyMessage(privKey, [pubKey], msg);
|
||||
return openpgp.decryptAndVerifyMessage(privKey, [pubKey], msg);
|
||||
|
||||
}).then(function(decrypted) {
|
||||
expect(decrypted).to.exist;
|
||||
expect(decrypted.signatures[0].valid).to.be.true;
|
||||
expect(decrypted.text).to.equal(message);
|
||||
|
@ -69,35 +68,44 @@ describe('Basic', function() {
|
|||
var userid = 'Test McTestington <test@example.com>';
|
||||
var passphrase = 'password';
|
||||
var message = 'hello world';
|
||||
var privKey;
|
||||
var pubKey;
|
||||
var msg;
|
||||
|
||||
var opt = {numBits: 512, userId: userid, passphrase: passphrase};
|
||||
openpgp.generateKeyPair(opt, function(err, key) {
|
||||
expect(err).to.not.exist;
|
||||
openpgp.generateKeyPair(opt).then(function(key) {
|
||||
|
||||
var privKeys = openpgp.key.readArmored(key.privateKeyArmored);
|
||||
var publicKeys = openpgp.key.readArmored(key.publicKeyArmored);
|
||||
|
||||
var privKey = privKeys.keys[0];
|
||||
var pubKey = publicKeys.keys[0];
|
||||
privKey = privKeys.keys[0];
|
||||
pubKey = publicKeys.keys[0];
|
||||
|
||||
var success = privKey.decrypt(passphrase);
|
||||
expect(success).to.be.true;
|
||||
|
||||
var encrypted = openpgp.signAndEncryptMessage([pubKey], privKey, message);
|
||||
return openpgp.signAndEncryptMessage([pubKey], privKey, message);
|
||||
|
||||
var msg = openpgp.message.readArmored(encrypted);
|
||||
}).then(function(encrypted) {
|
||||
|
||||
msg = openpgp.message.readArmored(encrypted);
|
||||
expect(msg).to.exist;
|
||||
|
||||
openpgp.generateKeyPair(opt, function(err, anotherKey) {
|
||||
expect(err).to.not.exist;
|
||||
return openpgp.generateKeyPair(opt);
|
||||
|
||||
var anotherPubKey = openpgp.key.readArmored(anotherKey.publicKeyArmored).keys[0];
|
||||
}).then(function(anotherKey) {
|
||||
|
||||
var anotherPubKey = openpgp.key.readArmored(anotherKey.publicKeyArmored).keys[0];
|
||||
|
||||
return openpgp.decryptAndVerifyMessage(privKey, [anotherPubKey], msg);
|
||||
|
||||
}).then(function(decrypted) {
|
||||
|
||||
expect(decrypted).to.exist;
|
||||
expect(decrypted.signatures[0].valid).to.be.null;
|
||||
expect(decrypted.text).to.equal(message);
|
||||
done();
|
||||
|
||||
var decrypted = openpgp.decryptAndVerifyMessage(privKey, [anotherPubKey], msg);
|
||||
expect(decrypted).to.exist;
|
||||
expect(decrypted.signatures[0].valid).to.be.null;
|
||||
expect(decrypted.text).to.equal(message);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -105,7 +113,9 @@ describe('Basic', function() {
|
|||
// init test data
|
||||
function randomString(length, chars) {
|
||||
var result = '';
|
||||
for (var i = length; i > 0; --i) result += chars[Math.round(Math.random() * (chars.length - 1))];
|
||||
for (var i = length; i > 0; --i) {
|
||||
result += chars[Math.round(Math.random() * (chars.length - 1))];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
var message = randomString(1024*1024*3, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
|
||||
|
@ -114,10 +124,7 @@ describe('Basic', function() {
|
|||
var passphrase = 'password';
|
||||
|
||||
var opt = {numBits: 512, userId: userid, passphrase: passphrase};
|
||||
openpgp.generateKeyPair(opt, function(err, key) {
|
||||
expect(err).to.not.exist;
|
||||
|
||||
var info = '\npassphrase: ' + passphrase + '\n' + 'userid: ' + userid + '\n' + 'message: ' + message;
|
||||
openpgp.generateKeyPair(opt).then(function(key) {
|
||||
|
||||
var privKeys = openpgp.key.readArmored(key.privateKeyArmored);
|
||||
var publicKeys = openpgp.key.readArmored(key.publicKeyArmored);
|
||||
|
@ -126,6 +133,7 @@ describe('Basic', function() {
|
|||
var pubKey = publicKeys.keys[0];
|
||||
|
||||
var success = privKey.decrypt(passphrase);
|
||||
expect(success).to.be.true;
|
||||
|
||||
if (console.profile) {
|
||||
console.profile("encrypt/sign/verify/decrypt");
|
||||
|
@ -148,13 +156,15 @@ describe('Basic', function() {
|
|||
|
||||
expect(keyids).to.exist;
|
||||
|
||||
var decrypted = openpgp.decryptAndVerifyMessage(privKey, [pubKey], msg);
|
||||
return openpgp.decryptAndVerifyMessage(privKey, [pubKey], msg);
|
||||
|
||||
}).then(function(decrypted) {
|
||||
|
||||
expect(decrypted).to.exist;
|
||||
expect(decrypted.signatures[0].valid).to.be.true;
|
||||
expect(decrypted.text).to.equal(message);
|
||||
|
||||
done();
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -240,30 +250,33 @@ describe('Basic', function() {
|
|||
|
||||
expect(pubKey).to.exist;
|
||||
|
||||
var encrypted = openpgp.encryptMessage([pubKey], plaintext);
|
||||
openpgp.encryptMessage([pubKey], plaintext).then(function(encrypted) {
|
||||
|
||||
expect(encrypted).to.exist;
|
||||
expect(encrypted).to.exist;
|
||||
|
||||
message = openpgp.message.readArmored(encrypted);
|
||||
message = openpgp.message.readArmored(encrypted);
|
||||
|
||||
expect(message).to.exist;
|
||||
expect(message).to.exist;
|
||||
|
||||
var privKeys = openpgp.key.readArmored(priv_key);
|
||||
var privKeys = openpgp.key.readArmored(priv_key);
|
||||
|
||||
expect(privKeys).to.exist;
|
||||
expect(privKeys.err).to.not.exist;
|
||||
expect(privKeys.keys).to.have.length(1);
|
||||
expect(privKeys).to.exist;
|
||||
expect(privKeys.err).to.not.exist;
|
||||
expect(privKeys.keys).to.have.length(1);
|
||||
|
||||
privKey = privKeys.keys[0];
|
||||
privKey = privKeys.keys[0];
|
||||
|
||||
expect(privKey).to.exist;
|
||||
expect(privKey).to.exist;
|
||||
|
||||
// get key IDs the message is encrypted for
|
||||
keyids = message.getEncryptionKeyIds();
|
||||
// get key IDs the message is encrypted for
|
||||
keyids = message.getEncryptionKeyIds();
|
||||
|
||||
expect(keyids).to.exist;
|
||||
expect(keyids).to.have.length(1);
|
||||
done();
|
||||
|
||||
});
|
||||
|
||||
expect(keyids).to.exist;
|
||||
expect(keyids).to.have.length(1);
|
||||
done();
|
||||
});
|
||||
|
||||
it('Decrypting key packet with wrong password returns false', function (done) {
|
||||
|
@ -274,15 +287,11 @@ describe('Basic', function() {
|
|||
done();
|
||||
});
|
||||
|
||||
var decrypted, error;
|
||||
|
||||
it('Calling decryptMessage with not decrypted key packet leads to exception', function (done) {
|
||||
function exceptionTest() {
|
||||
decrypted = openpgp.decryptMessage(privKey, message);
|
||||
}
|
||||
|
||||
expect(exceptionTest).to.throw(Error);
|
||||
done();
|
||||
openpgp.decryptMessage(privKey, message).catch(function(error) {
|
||||
expect(error).to.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Decrypting key packet with correct password returns true', function (done) {
|
||||
|
@ -293,16 +302,23 @@ describe('Basic', function() {
|
|||
});
|
||||
|
||||
it('Encrypt plain text and afterwards decrypt leads to same result', function (done) {
|
||||
decrypted = openpgp.decryptMessage(privKey, message);
|
||||
expect(decrypted).to.exist;
|
||||
expect(decrypted).to.equal(plaintext);
|
||||
done();
|
||||
openpgp.decryptMessage(privKey, message).then(function(decrypted) {
|
||||
expect(decrypted).to.exist;
|
||||
expect(decrypted).to.equal(plaintext);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Decrypt message 2x', function() {
|
||||
decrypted = openpgp.decryptMessage(privKey, message);
|
||||
var decrypted2 = openpgp.decryptMessage(privKey, message);
|
||||
expect(decrypted).to.equal(decrypted2);
|
||||
it('Decrypt message 2x', function(done) {
|
||||
var decrypted1;
|
||||
|
||||
openpgp.decryptMessage(privKey, message).then(function(decrypted) {
|
||||
decrypted1 = decrypted;
|
||||
return openpgp.decryptMessage(privKey, message);
|
||||
}).then(function(decrypted2) {
|
||||
expect(decrypted1).to.equal(decrypted2);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -360,15 +376,17 @@ describe('Basic', function() {
|
|||
'-----END PGP PRIVATE KEY BLOCK-----'].join('\n');
|
||||
|
||||
it('Decrypt message', function (done) {
|
||||
var privKey, message, decrypted;
|
||||
var privKey, message;
|
||||
|
||||
privKey = openpgp.key.readArmored(priv_key).keys[0];
|
||||
privKey.decrypt('1234');
|
||||
message = openpgp.message.readArmored(pgp_msg);
|
||||
decrypted = openpgp.decryptMessage(privKey, message);
|
||||
|
||||
expect(decrypted).to.equal('hello 3des\n');
|
||||
done();
|
||||
openpgp.decryptMessage(privKey, message).then(function(decrypted) {
|
||||
expect(decrypted).to.equal('hello 3des\n');
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -635,8 +635,7 @@ var pgp_desktop_priv =
|
|||
expect(key.users[0].selfCertifications[0].features).to.eql(openpgp.config.integrity_protect ? [1] : null); // modification detection
|
||||
};
|
||||
var opt = {numBits: 512, userId: 'test', passphrase: 'hello'};
|
||||
openpgp.generateKeyPair(opt, function(err, key) {
|
||||
expect(err).to.not.exist;
|
||||
openpgp.generateKeyPair(opt).then(function(key) {
|
||||
testPref(key.key);
|
||||
testPref(openpgp.key.readArmored(key.publicKeyArmored).keys[0]);
|
||||
done();
|
||||
|
@ -659,8 +658,7 @@ var pgp_desktop_priv =
|
|||
|
||||
it('Generated key is not unlocked by default', function(done) {
|
||||
var opt = {numBits: 512, userId: 'test', passphrase: '123'};
|
||||
openpgp.generateKeyPair(opt, function(err, key) {
|
||||
expect(err).to.not.exist;
|
||||
openpgp.generateKeyPair(opt).then(function(key) {
|
||||
var msg = openpgp.message.fromText('hello').encrypt([key.key]);
|
||||
msg = msg.decrypt.bind(msg, key.key);
|
||||
expect(msg).to.throw('Private key is not decrypted.');
|
||||
|
|
|
@ -119,15 +119,13 @@ describe("Packet", function() {
|
|||
it('Public key encrypted symmetric key packet', function(done) {
|
||||
var rsa = new openpgp.crypto.publicKey.rsa();
|
||||
|
||||
rsa.generate(512, "10001", function(error, mpiGen) {
|
||||
expect(error).to.not.exist;
|
||||
rsa.generate(512, "10001").then(function(mpiGen) {
|
||||
|
||||
var mpi = [mpiGen.n, mpiGen.ee, mpiGen.d, mpiGen.p, mpiGen.q, mpiGen.u];
|
||||
|
||||
mpi = mpi.map(function(k) {
|
||||
var mpi = new openpgp.MPI();
|
||||
mpi.fromBigInteger(k);
|
||||
return mpi;
|
||||
var mpi = new openpgp.MPI();
|
||||
mpi.fromBigInteger(k);
|
||||
return mpi;
|
||||
});
|
||||
|
||||
var enc = new openpgp.packet.PublicKeyEncryptedSessionKey(),
|
||||
|
@ -380,50 +378,44 @@ describe("Packet", function() {
|
|||
|
||||
it('Writing and encryption of a secret key packet.', function(done) {
|
||||
var key = new openpgp.packet.List();
|
||||
key.push(new openpgp.packet.SecretKey);
|
||||
key.push(new openpgp.packet.SecretKey());
|
||||
|
||||
var rsa = new openpgp.crypto.publicKey.rsa();
|
||||
|
||||
rsa.generate(512, "10001", function(err, mipGen) {
|
||||
expect(err).to.not.exist;
|
||||
rsa.generate(512, "10001").then(function(mipGen) {
|
||||
var mpi = [mipGen.n, mipGen.ee, mipGen.d, mipGen.p, mipGen.q, mipGen.u];
|
||||
mpi = mpi.map(function(k) {
|
||||
var mpi = new openpgp.MPI();
|
||||
mpi.fromBigInteger(k);
|
||||
return mpi;
|
||||
});
|
||||
|
||||
var mpi = [mipGen.n, mipGen.ee, mipGen.d, mipGen.p, mipGen.q, mipGen.u];
|
||||
key[0].mpi = mpi;
|
||||
|
||||
mpi = mpi.map(function(k) {
|
||||
var mpi = new openpgp.MPI();
|
||||
mpi.fromBigInteger(k);
|
||||
return mpi;
|
||||
});
|
||||
key[0].encrypt('hello');
|
||||
|
||||
key[0].mpi = mpi;
|
||||
var raw = key.write();
|
||||
|
||||
key[0].encrypt('hello');
|
||||
var key2 = new openpgp.packet.List();
|
||||
key2.read(raw);
|
||||
key2[0].decrypt('hello');
|
||||
|
||||
var raw = key.write();
|
||||
|
||||
var key2 = new openpgp.packet.List();
|
||||
key2.read(raw);
|
||||
key2[0].decrypt('hello');
|
||||
|
||||
expect(key[0].mpi.toString()).to.equal(key2[0].mpi.toString());
|
||||
done();
|
||||
expect(key[0].mpi.toString()).to.equal(key2[0].mpi.toString());
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Writing and verification of a signature packet.', function(done) {
|
||||
var key = new openpgp.packet.SecretKey();
|
||||
|
||||
var rsa = new openpgp.crypto.publicKey.rsa;
|
||||
|
||||
rsa.generate(512, "10001", function(err, mpiGen) {
|
||||
expect(err).to.not.exist;
|
||||
var rsa = new openpgp.crypto.publicKey.rsa();
|
||||
|
||||
rsa.generate(512, "10001").then(function(mpiGen) {
|
||||
var mpi = [mpiGen.n, mpiGen.ee, mpiGen.d, mpiGen.p, mpiGen.q, mpiGen.u];
|
||||
|
||||
mpi = mpi.map(function(k) {
|
||||
var mpi = new openpgp.MPI();
|
||||
mpi.fromBigInteger(k);
|
||||
return mpi;
|
||||
var mpi = new openpgp.MPI();
|
||||
mpi.fromBigInteger(k);
|
||||
return mpi;
|
||||
});
|
||||
|
||||
key.mpi = mpi;
|
||||
|
|
|
@ -262,10 +262,11 @@ describe("Signature", function() {
|
|||
var pub_key = openpgp.key.readArmored(pub_key_arm1).keys[0];
|
||||
var msg = openpgp.message.readArmored(msg_arm1);
|
||||
priv_key.decrypt("abcd");
|
||||
var decrypted = openpgp.decryptAndVerifyMessage(priv_key, [pub_key], msg);
|
||||
expect(decrypted).to.exist;
|
||||
expect(decrypted.signatures[0].valid).to.be.true;
|
||||
done();
|
||||
openpgp.decryptAndVerifyMessage(priv_key, [pub_key], msg).then(function(decrypted) {
|
||||
expect(decrypted).to.exist;
|
||||
expect(decrypted.signatures[0].valid).to.be.true;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Testing GnuPG stripped-key extensions', function(done) {
|
||||
|
@ -383,13 +384,13 @@ describe("Signature", function() {
|
|||
var keyids = esMsg.getEncryptionKeyIds();
|
||||
privKey.decryptKeyPacket(keyids, 'hello world');
|
||||
|
||||
var decrypted = openpgp.decryptAndVerifyMessage(privKey, [pubKey], esMsg);
|
||||
|
||||
expect(decrypted).to.exist;
|
||||
expect(decrypted.text).to.equal(plaintext);
|
||||
expect(decrypted.signatures).to.have.length(1);
|
||||
expect(decrypted.signatures[0].valid).to.be.true;
|
||||
done();
|
||||
openpgp.decryptAndVerifyMessage(privKey, [pubKey], esMsg).then(function(decrypted) {
|
||||
expect(decrypted).to.exist;
|
||||
expect(decrypted.text).to.equal(plaintext);
|
||||
expect(decrypted.signatures).to.have.length(1);
|
||||
expect(decrypted.signatures[0].valid).to.be.true;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Verify signature of signed and encrypted message from PGP 10.3.0 with openpgp.decryptAndVerifyMessage', function(done) {
|
||||
|
@ -419,13 +420,14 @@ describe("Signature", function() {
|
|||
var keyids = esMsg.getEncryptionKeyIds();
|
||||
privKey.decryptKeyPacket(keyids, 'hello world');
|
||||
|
||||
var decrypted = openpgp.decryptAndVerifyMessage(privKey, [pubKey], esMsg);
|
||||
openpgp.decryptAndVerifyMessage(privKey, [pubKey], esMsg).then(function(decrypted) {
|
||||
expect(decrypted).to.exist;
|
||||
expect(decrypted.text).to.equal(plaintext);
|
||||
expect(decrypted.signatures).to.have.length(1);
|
||||
expect(decrypted.signatures[0].valid).to.be.true;
|
||||
done();
|
||||
});
|
||||
|
||||
expect(decrypted).to.exist;
|
||||
expect(decrypted.text).to.equal(plaintext);
|
||||
expect(decrypted.signatures).to.have.length(1);
|
||||
expect(decrypted.signatures[0].valid).to.be.true;
|
||||
done();
|
||||
});
|
||||
|
||||
it('Verify signed message with two one pass signatures', function(done) {
|
||||
|
@ -504,14 +506,14 @@ describe("Signature", function() {
|
|||
expect(pubKey2.getKeyPacket(keyids)).to.exist;
|
||||
expect(pubKey3.getKeyPacket(keyids)).to.exist;
|
||||
|
||||
var cleartextSig = openpgp.verifyClearSignedMessage([pubKey2, pubKey3], csMsg);
|
||||
|
||||
expect(cleartextSig).to.exist;
|
||||
expect(cleartextSig.text).to.equal(plaintext);
|
||||
expect(cleartextSig.signatures).to.have.length(2);
|
||||
expect(cleartextSig.signatures[0].valid).to.be.true;
|
||||
expect(cleartextSig.signatures[1].valid).to.be.true;
|
||||
done();
|
||||
openpgp.verifyClearSignedMessage([pubKey2, pubKey3], csMsg).then(function(cleartextSig) {
|
||||
expect(cleartextSig).to.exist;
|
||||
expect(cleartextSig.text).to.equal(plaintext);
|
||||
expect(cleartextSig.signatures).to.have.length(2);
|
||||
expect(cleartextSig.signatures[0].valid).to.be.true;
|
||||
expect(cleartextSig.signatures[1].valid).to.be.true;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Sign text with openpgp.signClearMessage and verify with openpgp.verifyClearSignedMessage leads to same cleartext and valid signatures', function(done) {
|
||||
|
@ -520,17 +522,19 @@ describe("Signature", function() {
|
|||
var privKey = openpgp.key.readArmored(priv_key_arm2).keys[0];
|
||||
privKey.getSigningKeyPacket().decrypt('hello world');
|
||||
|
||||
var clearSignedArmor = openpgp.signClearMessage([privKey], plaintext);
|
||||
openpgp.signClearMessage([privKey], plaintext).then(function(clearSignedArmor) {
|
||||
|
||||
var csMsg = openpgp.cleartext.readArmored(clearSignedArmor);
|
||||
var csMsg = openpgp.cleartext.readArmored(clearSignedArmor);
|
||||
return openpgp.verifyClearSignedMessage([pubKey], csMsg);
|
||||
|
||||
var cleartextSig = openpgp.verifyClearSignedMessage([pubKey], csMsg);
|
||||
}).then(function(cleartextSig) {
|
||||
expect(cleartextSig).to.exist;
|
||||
expect(cleartextSig.text).to.equal(plaintext.replace(/\r/g,''));
|
||||
expect(cleartextSig.signatures).to.have.length(1);
|
||||
expect(cleartextSig.signatures[0].valid).to.be.true;
|
||||
done();
|
||||
});
|
||||
|
||||
expect(cleartextSig).to.exist;
|
||||
expect(cleartextSig.text).to.equal(plaintext.replace(/\r/g,''));
|
||||
expect(cleartextSig.signatures).to.have.length(1);
|
||||
expect(cleartextSig.signatures[0].valid).to.be.true;
|
||||
done();
|
||||
});
|
||||
|
||||
it('Verify primary key revocation signature', function(done) {
|
||||
|
@ -638,9 +642,7 @@ describe("Signature", function() {
|
|||
|
||||
it('Sign message with key without password', function(done) {
|
||||
var opt = {numBits: 512, userId: 'ABC', passphrase: null};
|
||||
openpgp.generateKeyPair(opt, function(err, gen) {
|
||||
expect(err).to.not.exist;
|
||||
|
||||
openpgp.generateKeyPair(opt).then(function(gen) {
|
||||
var key = gen.key;
|
||||
|
||||
var message = openpgp.message.fromText('hello world');
|
||||
|
|
|
@ -9,7 +9,10 @@
|
|||
<body>
|
||||
<div id="mocha"></div>
|
||||
|
||||
<!--<script src="lib/jquery.min.js"></script>-->
|
||||
<!-- polyfills -->
|
||||
<script src="lib/promise-1.0.0.js"></script>
|
||||
|
||||
<!-- libs -->
|
||||
<script src="../dist/openpgp.js"></script>
|
||||
<script src="lib/chai.js"></script>
|
||||
<script src="lib/mocha.js"></script>
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
if (typeof window === 'undefined') {
|
||||
// load ES6 Promises polyfill under node.js
|
||||
require('es6-promise').polyfill();
|
||||
}
|
||||
|
||||
describe('Unit Tests', function () {
|
||||
require('./general');
|
||||
require('./crypto');
|
||||
|
|
Loading…
Reference in New Issue
Block a user