Cleanups and doc fixes

This commit is contained in:
Mahrud Sayrafi 2018-01-31 04:20:21 -08:00
parent aba8a7a647
commit d97bc064ea
No known key found for this signature in database
GPG Key ID: C24071B956C3245F
12 changed files with 115 additions and 113 deletions

View File

@ -20,16 +20,17 @@
* @requires encoding/armor * @requires encoding/armor
* @requires enums * @requires enums
* @requires packet * @requires packet
* @requires signature
* @module cleartext * @module cleartext
*/ */
'use strict'; 'use strict';
import config from './config'; import config from './config';
import packet from './packet';
import enums from './enums.js';
import armor from './encoding/armor.js'; import armor from './encoding/armor.js';
import * as sigModule from './signature.js'; import enums from './enums.js';
import packet from './packet';
import { Signature } from './signature.js';
/** /**
* @class * @class
@ -45,10 +46,10 @@ export function CleartextMessage(text, signature) {
} }
// normalize EOL to canonical form <CR><LF> // normalize EOL to canonical form <CR><LF>
this.text = text.replace(/\r/g, '').replace(/[\t ]+\n/g, "\n").replace(/\n/g,"\r\n"); this.text = text.replace(/\r/g, '').replace(/[\t ]+\n/g, "\n").replace(/\n/g,"\r\n");
if (signature && !(signature instanceof sigModule.Signature)) { if (signature && !(signature instanceof Signature)) {
throw new Error('Invalid signature input'); throw new Error('Invalid signature input');
} }
this.signature = signature || new sigModule.Signature(new packet.List()); this.signature = signature || new Signature(new packet.List());
} }
/** /**
@ -105,7 +106,7 @@ CleartextMessage.prototype.signDetached = async function(privateKeys) {
signatureList.forEach(signaturePacket => packetlist.push(signaturePacket)); signatureList.forEach(signaturePacket => packetlist.push(signaturePacket));
}); });
return new sigModule.Signature(packetlist); return new Signature(packetlist);
}; };
/** /**
@ -131,24 +132,21 @@ CleartextMessage.prototype.verifyDetached = function(signature, keys) {
var keyPacket = null; var keyPacket = null;
await Promise.all(keys.map(async function(key) { await Promise.all(keys.map(async function(key) {
await key.verifyPrimaryUser(); await key.verifyPrimaryUser();
// Look for the unique key packet that matches issuerKeyId of signature
var result = key.getSigningKeyPacket(signature.issuerKeyId, config.verify_expired_keys); var result = key.getSigningKeyPacket(signature.issuerKeyId, config.verify_expired_keys);
if (result) { if (result) {
keyPacket = result; keyPacket = result;
} }
})); }));
var verifiedSig = {}; var verifiedSig = {
if (keyPacket) { keyid: signature.issuerKeyId,
verifiedSig.keyid = signature.issuerKeyId; valid: keyPacket ? await signature.verify(keyPacket, literalDataPacket) : null
verifiedSig.valid = await signature.verify(keyPacket, literalDataPacket); };
} else {
verifiedSig.keyid = signature.issuerKeyId;
verifiedSig.valid = null;
}
var packetlist = new packet.List(); var packetlist = new packet.List();
packetlist.push(signature); packetlist.push(signature);
verifiedSig.signature = new sigModule.Signature(packetlist); verifiedSig.signature = new Signature(packetlist);
return verifiedSig; return verifiedSig;
})); }));
@ -191,7 +189,7 @@ export function readArmored(armoredText) {
var packetlist = new packet.List(); var packetlist = new packet.List();
packetlist.read(input.data); packetlist.read(input.data);
verifyHeaders(input.headers, packetlist); verifyHeaders(input.headers, packetlist);
var signature = new sigModule.Signature(packetlist); var signature = new Signature(packetlist);
var newMessage = new CleartextMessage(input.text, signature); var newMessage = new CleartextMessage(input.text, signature);
return newMessage; return newMessage;
} }

View File

@ -30,7 +30,7 @@ const webCrypto = util.getWebCrypto(); // no GCM support in IE11, Safari 9
const nodeCrypto = util.getNodeCrypto(); const nodeCrypto = util.getNodeCrypto();
const Buffer = util.getNodeBuffer(); const Buffer = util.getNodeBuffer();
export const ivLength = 12; // size of the IV in bytes const ivLength = 12; // size of the IV in bytes
const TAG_LEN = 16; // size of the tag in bytes const TAG_LEN = 16; // size of the tag in bytes
const ALGO = 'AES-GCM'; const ALGO = 'AES-GCM';
@ -42,7 +42,7 @@ const ALGO = 'AES-GCM';
* @param {Uint8Array} iv The initialization vector (12 bytes) * @param {Uint8Array} iv The initialization vector (12 bytes)
* @return {Promise<Uint8Array>} The ciphertext output * @return {Promise<Uint8Array>} The ciphertext output
*/ */
export function encrypt(cipher, plaintext, key, iv) { function encrypt(cipher, plaintext, key, iv) {
if (cipher.substr(0,3) !== 'aes') { if (cipher.substr(0,3) !== 'aes') {
return Promise.reject(new Error('GCM mode supports only AES cipher')); return Promise.reject(new Error('GCM mode supports only AES cipher'));
} }
@ -64,7 +64,7 @@ export function encrypt(cipher, plaintext, key, iv) {
* @param {Uint8Array} iv The initialization vector (12 bytes) * @param {Uint8Array} iv The initialization vector (12 bytes)
* @return {Promise<Uint8Array>} The plaintext output * @return {Promise<Uint8Array>} The plaintext output
*/ */
export function decrypt(cipher, ciphertext, key, iv) { function decrypt(cipher, ciphertext, key, iv) {
if (cipher.substr(0,3) !== 'aes') { if (cipher.substr(0,3) !== 'aes') {
return Promise.reject(new Error('GCM mode supports only AES cipher')); return Promise.reject(new Error('GCM mode supports only AES cipher'));
} }
@ -78,6 +78,12 @@ export function decrypt(cipher, ciphertext, key, iv) {
} }
} }
export default {
ivLength,
encrypt,
decrypt
};
////////////////////////// //////////////////////////
// // // //

View File

@ -8,7 +8,7 @@
import cipher from './cipher'; import cipher from './cipher';
import hash from './hash'; import hash from './hash';
import cfb from './cfb'; import cfb from './cfb';
import * as gcm from './gcm'; import gcm from './gcm';
import publicKey from './public_key'; import publicKey from './public_key';
import signature from './signature'; import signature from './signature';
import random from './random'; import random from './random';

View File

@ -193,7 +193,7 @@ async function generate(curve) {
}; };
} }
function getPreferredHashAlgorithm(oid) { function getPreferredHashAlgo(oid) {
return curves[enums.write(enums.curve, oid.toHex())].hash; return curves[enums.write(enums.curve, oid.toHex())].hash;
} }
@ -202,7 +202,7 @@ module.exports = {
curves: curves, curves: curves,
webCurves: webCurves, webCurves: webCurves,
nodeCurves: nodeCurves, nodeCurves: nodeCurves,
getPreferredHashAlgorithm: getPreferredHashAlgorithm, getPreferredHashAlgo: getPreferredHashAlgo,
generate: generate, generate: generate,
get: get get: get
}; };

View File

@ -27,7 +27,7 @@
'use strict'; 'use strict';
import {get, generate, getPreferredHashAlgorithm} from './curves'; import {get, generate, getPreferredHashAlgo} from './curves';
import ecdsa from './ecdsa'; import ecdsa from './ecdsa';
import eddsa from './eddsa'; import eddsa from './eddsa';
import ecdh from './ecdh'; import ecdh from './ecdh';
@ -38,5 +38,5 @@ module.exports = {
ecdh: ecdh, ecdh: ecdh,
get: get, get: get,
generate: generate, generate: generate,
getPreferredHashAlgorithm: getPreferredHashAlgorithm getPreferredHashAlgo: getPreferredHashAlgo
}; };

View File

@ -17,20 +17,22 @@
/** /**
* @requires config * @requires config
* @requires crypto
* @requires encoding/armor * @requires encoding/armor
* @requires enums * @requires enums
* @requires util
* @requires packet * @requires packet
* @module key * @module key
*/ */
'use strict'; 'use strict';
import packet from './packet';
import enums from './enums.js';
import armor from './encoding/armor.js';
import config from './config'; import config from './config';
import util from './util';
import crypto from './crypto'; import crypto from './crypto';
import armor from './encoding/armor.js';
import enums from './enums.js';
import util from './util';
import packet from './packet';
/** /**
* @class * @class
@ -824,7 +826,7 @@ User.prototype.sign = async function(primaryKey, privateKeys) {
signaturePacket.signatureType = enums.write(enums.signature, enums.signature.cert_generic); signaturePacket.signatureType = enums.write(enums.signature, enums.signature.cert_generic);
signaturePacket.keyFlags = [enums.keyFlags.certify_keys | enums.keyFlags.sign_data]; signaturePacket.keyFlags = [enums.keyFlags.certify_keys | enums.keyFlags.sign_data];
signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm; signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm;
signaturePacket.hashAlgorithm = getPreferredHashAlgorithm(privateKey); signaturePacket.hashAlgorithm = getPreferredHashAlgo(privateKey);
signaturePacket.signingKeyId = signingKeyPacket.getKeyId(); signaturePacket.signingKeyId = signingKeyPacket.getKeyId();
signaturePacket.sign(signingKeyPacket, dataToSign); signaturePacket.sign(signingKeyPacket, dataToSign);
return signaturePacket; return signaturePacket;
@ -1296,7 +1298,7 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPacket, options) {
var signaturePacket = new packet.Signature(); var signaturePacket = new packet.Signature();
signaturePacket.signatureType = enums.signature.cert_generic; signaturePacket.signatureType = enums.signature.cert_generic;
signaturePacket.publicKeyAlgorithm = options.keyType; signaturePacket.publicKeyAlgorithm = options.keyType;
signaturePacket.hashAlgorithm = getPreferredHashAlgorithm(secretKeyPacket); signaturePacket.hashAlgorithm = getPreferredHashAlgo(secretKeyPacket);
signaturePacket.keyFlags = [enums.keyFlags.certify_keys | enums.keyFlags.sign_data]; signaturePacket.keyFlags = [enums.keyFlags.certify_keys | enums.keyFlags.sign_data];
signaturePacket.preferredSymmetricAlgorithms = []; signaturePacket.preferredSymmetricAlgorithms = [];
// prefer aes256, aes128, then aes192 (no WebCrypto support: https://www.chromium.org/blink/webcrypto#TOC-AES-support) // prefer aes256, aes128, then aes192 (no WebCrypto support: https://www.chromium.org/blink/webcrypto#TOC-AES-support)
@ -1340,7 +1342,7 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPacket, options) {
var subkeySignaturePacket = new packet.Signature(); var subkeySignaturePacket = new packet.Signature();
subkeySignaturePacket.signatureType = enums.signature.subkey_binding; subkeySignaturePacket.signatureType = enums.signature.subkey_binding;
subkeySignaturePacket.publicKeyAlgorithm = options.keyType; subkeySignaturePacket.publicKeyAlgorithm = options.keyType;
subkeySignaturePacket.hashAlgorithm = getPreferredHashAlgorithm(secretSubkeyPacket); subkeySignaturePacket.hashAlgorithm = getPreferredHashAlgo(secretSubkeyPacket);
subkeySignaturePacket.keyFlags = [enums.keyFlags.encrypt_communication | enums.keyFlags.encrypt_storage]; subkeySignaturePacket.keyFlags = [enums.keyFlags.encrypt_communication | enums.keyFlags.encrypt_storage];
if (options.keyExpirationTime > 0) { if (options.keyExpirationTime > 0) {
subkeySignaturePacket.keyExpirationTime = options.keyExpirationTime; subkeySignaturePacket.keyExpirationTime = options.keyExpirationTime;
@ -1364,7 +1366,7 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPacket, options) {
* @param {object} key * @param {object} key
* @return {String} * @return {String}
*/ */
export function getPreferredHashAlgorithm(key) { export function getPreferredHashAlgo(key) {
var hash_algo = config.prefer_hash_algorithm, var hash_algo = config.prefer_hash_algorithm,
pref_algo = hash_algo; pref_algo = hash_algo;
if (Key.prototype.isPrototypeOf(key)) { if (Key.prototype.isPrototypeOf(key)) {
@ -1385,7 +1387,7 @@ export function getPreferredHashAlgorithm(key) {
case 'ecdh': case 'ecdh':
case 'ecdsa': case 'ecdsa':
case 'eddsa': case 'eddsa':
pref_algo = crypto.publicKey.elliptic.getPreferredHashAlgorithm(key.params[0]); pref_algo = crypto.publicKey.elliptic.getPreferredHashAlgo(key.params[0]);
} }
} }
return crypto.hash.getHashByteLength(hash_algo) <= crypto.hash.getHashByteLength(pref_algo) ? return crypto.hash.getHashByteLength(hash_algo) <= crypto.hash.getHashByteLength(pref_algo) ?

View File

@ -17,22 +17,22 @@
/** /**
* The class that deals with storage of the keyring. Currently the only option is to use HTML5 local storage. * The class that deals with storage of the keyring. Currently the only option is to use HTML5 local storage.
* @requires enums
* @requires key * @requires key
* @requires util * @requires keyring/localstore
* @module keyring/keyring * @module keyring/keyring
* @param {keyring/localstore} [storeHandler] class implementing loadPublic(), loadPrivate(), storePublic(), and storePrivate() methods
*/ */
'use strict'; 'use strict';
import * as keyModule from '../key.js'; import { readArmored } from '../key.js';
import LocalStore from './localstore.js'; import LocalStore from './localstore.js';
/** /**
* Initialization routine for the keyring. This method reads the * Initialization routine for the keyring. This method reads the
* keyring from HTML5 local storage and initializes this instance. * keyring from HTML5 local storage and initializes this instance.
* @constructor * @constructor
* @param {class} [storeHandler] class implementing loadPublic(), loadPrivate(), storePublic(), and storePrivate() methods * @param {keyring/localstore} [storeHandler] class implementing loadPublic(), loadPrivate(), storePublic(), and storePrivate() methods
*/ */
export default function Keyring(storeHandler) { export default function Keyring(storeHandler) {
this.storeHandler = storeHandler || new LocalStore(); this.storeHandler = storeHandler || new LocalStore();
@ -181,7 +181,7 @@ KeyArray.prototype.getForId = function (keyId, deep) {
* @return {Array<Error>|null} array of error objects or null * @return {Array<Error>|null} array of error objects or null
*/ */
KeyArray.prototype.importKey = function (armored) { KeyArray.prototype.importKey = function (armored) {
var imported = keyModule.readArmored(armored); var imported = readArmored(armored);
var that = this; var that = this;
imported.keys.forEach(async function(key) { imported.keys.forEach(async function(key) {
// check if key already in key array // check if key already in key array

View File

@ -18,6 +18,8 @@
/** /**
* The class that deals with storage of the keyring. Currently the only option is to use HTML5 local storage. * The class that deals with storage of the keyring. Currently the only option is to use HTML5 local storage.
* @requires config * @requires config
* @requires key
* @requires util
* @module keyring/localstore * @module keyring/localstore
* @param {String} prefix prefix for itemnames in localstore * @param {String} prefix prefix for itemnames in localstore
*/ */
@ -25,7 +27,7 @@
'use strict'; 'use strict';
import config from '../config'; import config from '../config';
import * as keyModule from '../key.js'; import { readArmored } from '../key.js';
import util from '../util.js'; import util from '../util.js';
export default function LocalStore(prefix) { export default function LocalStore(prefix) {
@ -67,7 +69,7 @@ function loadKeys(storage, itemname) {
if (armoredKeys !== null && armoredKeys.length !== 0) { if (armoredKeys !== null && armoredKeys.length !== 0) {
var key; var key;
for (var i = 0; i < armoredKeys.length; i++) { for (var i = 0; i < armoredKeys.length; i++) {
key = keyModule.readArmored(armoredKeys[i]); key = readArmored(armoredKeys[i]);
if (!key.err) { if (!key.err) {
keys.push(key.keys[0]); keys.push(key.keys[0]);
} else { } else {

View File

@ -20,20 +20,24 @@
* @requires crypto * @requires crypto
* @requires encoding/armor * @requires encoding/armor
* @requires enums * @requires enums
* @requires util
* @requires packet * @requires packet
* @requires signature
* @requires key
* @module message * @module message
*/ */
'use strict'; 'use strict';
import util from './util.js';
import packet from './packet';
import enums from './enums.js';
import armor from './encoding/armor.js';
import config from './config'; import config from './config';
import crypto from './crypto'; import crypto from './crypto';
import * as sigModule from './signature.js'; import armor from './encoding/armor.js';
import * as keyModule from './key.js'; import enums from './enums.js';
import util from './util.js';
import packet from './packet';
import { Signature } from './signature.js';
import { getPreferredHashAlgo, getPreferredSymAlgo } from './key.js';
/** /**
* @class * @class
@ -228,7 +232,7 @@ Message.prototype.encrypt = function(keys, passwords, sessionKey) {
symAlgo = sessionKey.algorithm; symAlgo = sessionKey.algorithm;
sessionKey = sessionKey.data; sessionKey = sessionKey.data;
} else if (keys && keys.length) { } else if (keys && keys.length) {
symAlgo = enums.read(enums.symmetric, keyModule.getPreferredSymAlgo(keys)); symAlgo = enums.read(enums.symmetric, getPreferredSymAlgo(keys));
} else if (passwords && passwords.length) { } else if (passwords && passwords.length) {
symAlgo = enums.read(enums.symmetric, config.encryption_cipher); symAlgo = enums.read(enums.symmetric, config.encryption_cipher);
} else { } else {
@ -361,7 +365,7 @@ Message.prototype.sign = async function(privateKeys=[], signature=null) {
onePassSig = new packet.OnePassSignature(); onePassSig = new packet.OnePassSignature();
onePassSig.type = signatureType; onePassSig.type = signatureType;
//TODO get preferred hash algo from key signature //TODO get preferred hash algo from key signature
onePassSig.hashAlgorithm = keyModule.getPreferredHashAlgorithm(privateKey); onePassSig.hashAlgorithm = getPreferredHashAlgo(privateKey);
onePassSig.publicKeyAlgorithm = signingKeyPacket.algorithm; onePassSig.publicKeyAlgorithm = signingKeyPacket.algorithm;
onePassSig.signingKeyId = signingKeyPacket.getKeyId(); onePassSig.signingKeyId = signingKeyPacket.getKeyId();
if (i === privateKeys.length - 1) { if (i === privateKeys.length - 1) {
@ -381,7 +385,7 @@ Message.prototype.sign = async function(privateKeys=[], signature=null) {
throw new Error('Private key is not decrypted.'); throw new Error('Private key is not decrypted.');
} }
signaturePacket.signatureType = signatureType; signaturePacket.signatureType = signatureType;
signaturePacket.hashAlgorithm = keyModule.getPreferredHashAlgorithm(privateKey); signaturePacket.hashAlgorithm = getPreferredHashAlgo(privateKey);
signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm; signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm;
await signaturePacket.sign(signingKeyPacket, literalDataPacket); await signaturePacket.sign(signingKeyPacket, literalDataPacket);
return signaturePacket; return signaturePacket;
@ -424,7 +428,7 @@ Message.prototype.signDetached = async function(privateKeys=[], signature=null)
} }
signaturePacket.signatureType = signatureType; signaturePacket.signatureType = signatureType;
signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm; signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm;
signaturePacket.hashAlgorithm = keyModule.getPreferredHashAlgorithm(privateKey); signaturePacket.hashAlgorithm = getPreferredHashAlgo(privateKey);
await signaturePacket.sign(signingKeyPacket, literalDataPacket); await signaturePacket.sign(signingKeyPacket, literalDataPacket);
return signaturePacket; return signaturePacket;
})).then(signatureList => { })).then(signatureList => {
@ -436,7 +440,7 @@ Message.prototype.signDetached = async function(privateKeys=[], signature=null)
packetlist.concat(existingSigPacketlist); packetlist.concat(existingSigPacketlist);
} }
return new sigModule.Signature(packetlist); return new Signature(packetlist);
}; };
@ -483,25 +487,22 @@ async function createVerificationObjects(signatureList, literalDataList, keys) {
var keyPacket = null; var keyPacket = null;
await Promise.all(keys.map(async function(key) { await Promise.all(keys.map(async function(key) {
await key.verifyPrimaryUser(); await key.verifyPrimaryUser();
// Look for the unique key packet that matches issuerKeyId of signature
var result = key.getSigningKeyPacket(signature.issuerKeyId, config.verify_expired_keys); var result = key.getSigningKeyPacket(signature.issuerKeyId, config.verify_expired_keys);
if (result) { if (result) {
keyPacket = result; keyPacket = result;
} }
})); }));
var verifiedSig = {}; // Look for the unique key packet that matches issuerKeyId of signature
if (keyPacket) { var verifiedSig = {
//found a key packet that matches keyId of signature keyid: signature.issuerKeyId,
verifiedSig.keyid = signature.issuerKeyId; valid: keyPacket ? await signature.verify(keyPacket, literalDataList[0]) : null
verifiedSig.valid = await signature.verify(keyPacket, literalDataList[0]); };
} else {
verifiedSig.keyid = signature.issuerKeyId;
verifiedSig.valid = null;
}
var packetlist = new packet.List(); var packetlist = new packet.List();
packetlist.push(signature); packetlist.push(signature);
verifiedSig.signature = new sigModule.Signature(packetlist); verifiedSig.signature = new Signature(packetlist);
return verifiedSig; return verifiedSig;
})); }));

View File

@ -16,11 +16,13 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
/** /**
* @requires ed6-promise
* @requires message * @requires message
* @requires cleartext * @requires cleartext
* @requires key * @requires key
* @requires config * @requires config
* @requires util * @requires util
* @requires worker/async_proxy
* @module openpgp * @module openpgp
*/ */
@ -35,8 +37,8 @@
import es6Promise from 'es6-promise'; import es6Promise from 'es6-promise';
import * as messageLib from './message.js'; import * as messageLib from './message.js';
import * as cleartext from './cleartext.js'; import { CleartextMessage } from './cleartext.js';
import * as key from './key.js'; import { generate, reformat } from './key.js';
import config from './config/config.js'; import config from './config/config.js';
import util from './util'; import util from './util';
import AsyncProxy from './worker/async_proxy.js'; import AsyncProxy from './worker/async_proxy.js';
@ -109,11 +111,11 @@ export function generateKey({ userIds=[], passphrase, numBits=2048, unlocked=fal
return asyncProxy.delegate('generateKey', options); return asyncProxy.delegate('generateKey', options);
} }
return key.generate(options).then(newKey => ({ return generate(options).then(key => ({
key: newKey, key: key,
privateKeyArmored: newKey.armor(), privateKeyArmored: key.armor(),
publicKeyArmored: newKey.toPublic().armor() publicKeyArmored: key.toPublic().armor()
})).catch(onError.bind(null, 'Error generating keypair')); })).catch(onError.bind(null, 'Error generating keypair'));
} }
@ -137,11 +139,11 @@ export function reformatKey({ privateKey, userIds=[], passphrase="", unlocked=fa
return asyncProxy.delegate('reformatKey', options); return asyncProxy.delegate('reformatKey', options);
} }
return key.reformat(options).then(newKey => ({ return reformat(options).then(key => ({
key: newKey, key: key,
privateKeyArmored: newKey.armor(), privateKeyArmored: key.armor(),
publicKeyArmored: newKey.toPublic().armor() publicKeyArmored: key.toPublic().armor()
})).catch(onError.bind(null, 'Error reformatting keypair')); })).catch(onError.bind(null, 'Error reformatting keypair'));
} }
@ -157,16 +159,15 @@ export function decryptKey({ privateKey, passphrase }) {
return asyncProxy.delegate('decryptKey', { privateKey, passphrase }); return asyncProxy.delegate('decryptKey', { privateKey, passphrase });
} }
return execute(() => { return Promise.resolve().then(async function() {
await privateKey.decrypt(passphrase);
if (!privateKey.decrypt(passphrase)) {
throw new Error('Invalid passphrase');
}
return { return {
key: privateKey key: privateKey
}; };
}, 'Error decrypting private key'); }).catch(onError.bind(null, 'Error decrypting private key'));
} }
@ -308,7 +309,7 @@ export function sign({ data, privateKeys, armor=true, detached=false}) {
var message; var message;
if (util.isString(data)) { if (util.isString(data)) {
message = new cleartext.CleartextMessage(data); message = new CleartextMessage(data);
} else { } else {
message = messageLib.fromBinary(data); message = messageLib.fromBinary(data);
} }
@ -353,7 +354,7 @@ export function verify({ message, publicKeys, signature=null }) {
return Promise.resolve().then(async function() { return Promise.resolve().then(async function() {
var result = {}; var result = {};
if (cleartext.CleartextMessage.prototype.isPrototypeOf(message)) { if (CleartextMessage.prototype.isPrototypeOf(message)) {
result.data = message.getText(); result.data = message.getText();
} else { } else {
result.data = message.getLiteralData(); result.data = message.getLiteralData();
@ -395,9 +396,11 @@ export function encryptSessionKey({ data, algorithm, publicKeys, passwords }) {
return asyncProxy.delegate('encryptSessionKey', { data, algorithm, publicKeys, passwords }); return asyncProxy.delegate('encryptSessionKey', { data, algorithm, publicKeys, passwords });
} }
return execute(async () => ({ return Promise.resolve().then(async function() {
message: await messageLib.encryptSessionKey(data, algorithm, publicKeys, passwords)
}), 'Error encrypting session key'); return { message: await messageLib.encryptSessionKey(data, algorithm, publicKeys, passwords) };
}).catch(onError.bind(null, 'Error encrypting session key'));
} }
/** /**
@ -418,7 +421,11 @@ export function decryptSessionKey({ message, privateKey, password }) {
return asyncProxy.delegate('decryptSessionKey', { message, privateKey, password }); return asyncProxy.delegate('decryptSessionKey', { message, privateKey, password });
} }
return execute(() => message.decryptSessionKey(privateKey, password), 'Error decrypting session key'); return Promise.resolve().then(async function() {
return message.decryptSessionKey(privateKey, password);
}).catch(onError.bind(null, 'Error decrypting session key'));
} }
@ -453,7 +460,7 @@ function checkMessage(message) {
} }
} }
function checkCleartextOrMessage(message) { function checkCleartextOrMessage(message) {
if (!cleartext.CleartextMessage.prototype.isPrototypeOf(message) && !messageLib.Message.prototype.isPrototypeOf(message)) { if (!CleartextMessage.prototype.isPrototypeOf(message) && !messageLib.Message.prototype.isPrototypeOf(message)) {
throw new Error('Parameter [message] needs to be of type Message or CleartextMessage'); throw new Error('Parameter [message] needs to be of type Message or CleartextMessage');
} }
} }
@ -540,20 +547,6 @@ function parseMessage(message, format) {
} }
} }
/**
* 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} message A human readable error Message
* @return {Promise} The promise wrapped around cmd
*/
function execute(cmd, message) {
// wrap the sync cmd in a promise
const promise = new Promise(resolve => resolve(cmd()));
// handler error globally
return promise.catch(onError.bind(null, message));
}
/** /**
* Global error handler that logs the stack trace and rethrows a high lvl error message. * 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 {String} message A human readable high level error Message

View File

@ -23,10 +23,10 @@
'use strict'; 'use strict';
import * as key from '../key.js'; import { Key } from '../key.js';
import * as message from '../message.js'; import { Message } from '../message.js';
import * as cleartext from '../cleartext.js'; import { CleartextMessage } from '../cleartext.js';
import * as signature from '../signature.js' import { Signature } from '../signature.js'
import Packetlist from './packetlist.js'; import Packetlist from './packetlist.js';
import type_keyid from '../type/keyid.js'; import type_keyid from '../type/keyid.js';
@ -58,13 +58,13 @@ export function clonePackets(options) {
} }
if (options.message) { if (options.message) {
//could be either a Message or CleartextMessage object //could be either a Message or CleartextMessage object
if (options.message instanceof message.Message) { if (options.message instanceof Message) {
options.message = options.message.packets; options.message = options.message.packets;
} else if (options.message instanceof cleartext.CleartextMessage) { } else if (options.message instanceof CleartextMessage) {
options.message.signature = options.message.signature.packets; options.message.signature = options.message.signature.packets;
} }
} }
if (options.signature && (options.signature instanceof signature.Signature)) { if (options.signature && (options.signature instanceof Signature)) {
options.signature = options.signature.packets; options.signature = options.signature.packets;
} }
if (options.signatures) { if (options.signatures) {
@ -120,23 +120,23 @@ export function parseClonedPackets(options, method) {
function packetlistCloneToKey(clone) { function packetlistCloneToKey(clone) {
const packetlist = Packetlist.fromStructuredClone(clone); const packetlist = Packetlist.fromStructuredClone(clone);
return new key.Key(packetlist); return new Key(packetlist);
} }
function packetlistCloneToMessage(clone) { function packetlistCloneToMessage(clone) {
const packetlist = Packetlist.fromStructuredClone(clone); const packetlist = Packetlist.fromStructuredClone(clone);
return new message.Message(packetlist); return new Message(packetlist);
} }
function packetlistCloneToCleartextMessage(clone) { function packetlistCloneToCleartextMessage(clone) {
var packetlist = Packetlist.fromStructuredClone(clone.signature); var packetlist = Packetlist.fromStructuredClone(clone.signature);
return new cleartext.CleartextMessage(clone.text, new signature.Signature(packetlist)); return new CleartextMessage(clone.text, new Signature(packetlist));
} }
//verification objects //verification objects
function packetlistCloneToSignatures(clone) { function packetlistCloneToSignatures(clone) {
clone.keyid = type_keyid.fromClone(clone.keyid); clone.keyid = type_keyid.fromClone(clone.keyid);
clone.signature = new signature.Signature(clone.signature); clone.signature = new Signature(clone.signature);
return clone; return clone;
} }
@ -146,5 +146,5 @@ function packetlistCloneToSignature(clone) {
return clone; return clone;
} }
var packetlist = Packetlist.fromStructuredClone(clone); var packetlist = Packetlist.fromStructuredClone(clone);
return new signature.Signature(packetlist); return new Signature(packetlist);
} }

View File

@ -286,16 +286,16 @@ describe('Elliptic Curve Cryptography', function () {
expect(verify_signature('p384', 8, p384_r, p384_s, p384_message, key_data.p384.pub)) expect(verify_signature('p384', 8, p384_r, p384_s, p384_message, key_data.p384.pub))
.to.eventually.be.true.notify(done); .to.eventually.be.true.notify(done);
}); });
it('Sign and verify message', function (done) { it('Sign and verify message', function () {
var curve = elliptic_curves.get('p521'); var curve = elliptic_curves.get('p521');
curve.genKeyPair().then(keyPair => { return curve.genKeyPair().then(keyPair => {
var keyPublic = bin2bi(keyPair.getPublic()); var keyPublic = bin2bi(keyPair.getPublic());
var keyPrivate = bin2bi(keyPair.getPrivate()); var keyPrivate = bin2bi(keyPair.getPrivate());
var oid = curve.oid; var oid = curve.oid;
var message = p384_message; var message = p384_message;
elliptic_curves.ecdsa.sign(oid, 10, message, keyPrivate).then(signature => { return elliptic_curves.ecdsa.sign(oid, 10, message, keyPrivate).then(signature => {
expect(elliptic_curves.ecdsa.verify(oid, 10, signature, message, keyPublic)) expect(elliptic_curves.ecdsa.verify(oid, 10, signature, message, keyPublic))
.to.eventually.be.true.notify(done); .to.eventually.be.true;
}); });
}); });
}); });