Remove internal streaming parameters

This commit is contained in:
Daniel Huigens 2021-03-24 21:51:27 +01:00
parent ff8d274b4d
commit 06aef92752
16 changed files with 79 additions and 93 deletions

View File

@ -71,7 +71,7 @@ export class CleartextMessage {
async sign(privateKeys, signature = null, signingKeyIDs = [], date = new Date(), userIDs = [], config = defaultConfig) {
const literalDataPacket = new LiteralDataPacket();
literalDataPacket.setText(this.text);
const newSignature = new Signature(await createSignaturePackets(literalDataPacket, privateKeys, signature, signingKeyIDs, date, userIDs, true, undefined, config));
const newSignature = new Signature(await createSignaturePackets(literalDataPacket, privateKeys, signature, signingKeyIDs, date, userIDs, true, config));
return new CleartextMessage(this.text, newSignature);
}
@ -90,7 +90,7 @@ export class CleartextMessage {
const literalDataPacket = new LiteralDataPacket();
// we assume that cleartext signature is generated based on UTF8 cleartext
literalDataPacket.setText(this.text);
return createVerificationObjects(signatureList, [literalDataPacket], keys, date, true, undefined, config);
return createVerificationObjects(signatureList, [literalDataPacket], keys, date, true, config);
}
/**

View File

@ -32,6 +32,9 @@ function nodeHash(type) {
function hashjsHash(hash, webCryptoHash) {
return async function(data, config = defaultConfig) {
if (stream.isArrayStream(data)) {
data = await stream.readToEnd(data);
}
if (!util.isStream(data) && webCrypto && webCryptoHash && data.length >= config.minBytesForWebCrypto) {
return new Uint8Array(await webCrypto.digest(webCryptoHash, data));
}
@ -44,6 +47,9 @@ function hashjsHash(hash, webCryptoHash) {
function asmcryptoHash(hash, webCryptoHash) {
return async function(data, config = defaultConfig) {
if (stream.isArrayStream(data)) {
data = await stream.readToEnd(data);
}
if (util.isStream(data)) {
const hashInstance = new hash();
return stream.transform(data, value => {

View File

@ -233,7 +233,7 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf
signatureType: enums.signature.keyRevocation,
reasonForRevocationFlag: enums.reasonForRevocation.noReason,
reasonForRevocationString: ''
}, options.date, undefined, undefined, undefined, config));
}, options.date, undefined, undefined, config));
// set passphrase protection
if (options.passphrase) {

View File

@ -51,7 +51,7 @@ export async function getLatestValidSignature(signatures, primaryKey, signatureT
!signatures[i].isExpired(date)
) {
// check binding signature is verified
signatures[i].verified || await signatures[i].verify(primaryKey, signatureType, dataToVerify, undefined, undefined, config);
signatures[i].verified || await signatures[i].verify(primaryKey, signatureType, dataToVerify, undefined, config);
signature = signatures[i];
}
} catch (e) {
@ -97,7 +97,7 @@ export async function createBindingSignature(subkey, primaryKey, options, config
subkeySignaturePacket.keyFlags = [enums.keyFlags.signData];
subkeySignaturePacket.embeddedSignature = await createSignaturePacket(dataToSign, null, subkey, {
signatureType: enums.signature.keyBinding
}, options.date, undefined, undefined, undefined, config);
}, options.date, undefined, undefined, config);
} else {
subkeySignaturePacket.keyFlags = [enums.keyFlags.encryptCommunication | enums.keyFlags.encryptStorage];
}
@ -193,12 +193,11 @@ export async function getPreferredAlgo(type, keys = [], date = new Date(), userI
* @param {Date} [date] - Override the creationtime of the signature
* @param {Object} [userID] - User ID
* @param {Object} [detached] - Whether to create a detached signature packet
* @param {Boolean} [streaming] - Whether to process data as a stream
* @param {Object} config - full configuration
* @returns {SignaturePacket} Signature packet.
* @async
*/
export async function createSignaturePacket(dataToSign, privateKey, signingKeyPacket, signatureProperties, date, userID, detached = false, streaming = false, config) {
export async function createSignaturePacket(dataToSign, privateKey, signingKeyPacket, signatureProperties, date, userID, detached = false, config) {
if (signingKeyPacket.isDummy()) {
throw new Error('Cannot sign with a gnu-dummy key.');
}
@ -209,7 +208,7 @@ export async function createSignaturePacket(dataToSign, privateKey, signingKeyPa
Object.assign(signaturePacket, signatureProperties);
signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm;
signaturePacket.hashAlgorithm = await getPreferredHashAlgo(privateKey, signingKeyPacket, date, userID, config);
await signaturePacket.sign(signingKeyPacket, dataToSign, detached, streaming);
await signaturePacket.sign(signingKeyPacket, dataToSign, detached);
return signaturePacket;
}
@ -272,7 +271,7 @@ export async function isDataRevoked(primaryKey, signatureType, dataToVerify, rev
(!signature || revocationSignature.issuerKeyID.equals(signature.issuerKeyID)) &&
!(config.revocationsExpire && revocationSignature.isExpired(normDate))
) {
revocationSignature.verified || await revocationSignature.verify(key, signatureType, dataToVerify, undefined, undefined, config);
revocationSignature.verified || await revocationSignature.verify(key, signatureType, dataToVerify, undefined, config);
// TODO get an identifier of the revoked object instead
revocationKeyIDs.push(revocationSignature.issuerKeyID);

View File

@ -768,7 +768,7 @@ class Key {
signatureType: enums.signature.keyRevocation,
reasonForRevocationFlag: enums.write(enums.reasonForRevocation, reasonForRevocationFlag),
reasonForRevocationString
}, date, undefined, undefined, undefined, config));
}, date, undefined, undefined, config));
return key;
}
@ -812,7 +812,7 @@ class Key {
throw new Error('Revocation signature is expired');
}
try {
await revocationSignature.verify(this.keyPacket, enums.signature.keyRevocation, { key: this.keyPacket }, undefined, undefined, config);
await revocationSignature.verify(this.keyPacket, enums.signature.keyRevocation, { key: this.keyPacket }, undefined, config);
} catch (e) {
throw util.wrapError('Could not verify revocation signature', e);
}

View File

@ -142,7 +142,7 @@ class SubKey {
}
}
try {
srcBindSig.verified || await srcBindSig.verify(primaryKey, enums.signature.subkeyBinding, dataToVerify, undefined, undefined, config);
srcBindSig.verified || await srcBindSig.verify(primaryKey, enums.signature.subkeyBinding, dataToVerify, undefined, config);
return true;
} catch (e) {
return false;
@ -180,7 +180,7 @@ class SubKey {
signatureType: enums.signature.subkeyRevocation,
reasonForRevocationFlag: enums.write(enums.reasonForRevocation, reasonForRevocationFlag),
reasonForRevocationString
}, date, undefined, undefined, undefined, config));
}, date, undefined, undefined, config));
await subKey.update(this, primaryKey);
return subKey;
}

View File

@ -64,7 +64,7 @@ class User {
// Most OpenPGP implementations use generic certification (0x10)
signatureType: enums.signature.certGeneric,
keyFlags: [enums.keyFlags.certifyKeys | enums.keyFlags.signData]
}, undefined, undefined, undefined, undefined, config);
}, undefined, undefined, undefined, config);
}));
await user.update(this, primaryKey);
return user;
@ -122,7 +122,7 @@ class User {
throw new Error('User certificate is revoked');
}
try {
certificate.verified || await certificate.verify(signingKey.keyPacket, enums.signature.certGeneric, dataToVerify, undefined, undefined, config);
certificate.verified || await certificate.verify(signingKey.keyPacket, enums.signature.certGeneric, dataToVerify, undefined, config);
} catch (e) {
throw util.wrapError('User certificate is invalid', e);
}
@ -186,7 +186,7 @@ class User {
throw new Error('Self-certification is revoked');
}
try {
selfCertification.verified || await selfCertification.verify(primaryKey, enums.signature.certGeneric, dataToVerify, undefined, undefined, config);
selfCertification.verified || await selfCertification.verify(primaryKey, enums.signature.certGeneric, dataToVerify, undefined, config);
} catch (e) {
throw util.wrapError('Self-certification is invalid', e);
}
@ -219,7 +219,7 @@ class User {
// self signatures
await mergeSignatures(user, this, 'selfCertifications', async function(srcSelfSig) {
try {
srcSelfSig.verified || await srcSelfSig.verify(primaryKey, enums.signature.certGeneric, dataToVerify, undefined, undefined, config);
srcSelfSig.verified || await srcSelfSig.verify(primaryKey, enums.signature.certGeneric, dataToVerify, undefined, config);
return true;
} catch (e) {
return false;

View File

@ -107,12 +107,11 @@ export class Message {
* @param {Array<Key>} [privateKeys] - Private keys with decrypted secret data
* @param {Array<String>} [passwords] - Passwords used to decrypt
* @param {Array<Object>} [sessionKeys] - Session keys in the form: { data:Uint8Array, algorithm:String, [aeadAlgorithm:String] }
* @param {Boolean} [streaming] - Whether to process data as a stream
* @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {Message} New message with decrypted content.
* @async
*/
async decrypt(privateKeys, passwords, sessionKeys, streaming, config = defaultConfig) {
async decrypt(privateKeys, passwords, sessionKeys, config = defaultConfig) {
const keyObjs = sessionKeys || await this.decryptSessionKeys(privateKeys, passwords, config);
const symEncryptedPacketlist = this.packets.filterByTag(
@ -133,7 +132,7 @@ export class Message {
}
try {
await symEncryptedPacket.decrypt(keyObj.algorithm, keyObj.data, streaming, config);
await symEncryptedPacket.decrypt(keyObj.algorithm, keyObj.data, config);
} catch (e) {
util.printDebugError(e);
exception = e;
@ -317,12 +316,11 @@ export class Message {
* @param {Array<module:type/keyid~KeyID>} [encryptionKeyIDs] - Array of key IDs to use for encryption. Each encryptionKeyIDs[i] corresponds to publicKeys[i]
* @param {Date} [date] - Override the creation date of the literal package
* @param {Array<Object>} [userIDs] - User IDs to encrypt for, e.g. [{ name:'Robert Receiver', email:'robert@openpgp.org' }]
* @param {Boolean} [streaming] - Whether to process data as a stream
* @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {Message} New message with encrypted content.
* @async
*/
async encrypt(keys, passwords, sessionKey, wildcard = false, encryptionKeyIDs = [], date = new Date(), userIDs = [], streaming, config = defaultConfig) {
async encrypt(keys, passwords, sessionKey, wildcard = false, encryptionKeyIDs = [], date = new Date(), userIDs = [], config = defaultConfig) {
if (sessionKey) {
if (!util.isUint8Array(sessionKey.data) || !util.isString(sessionKey.algorithm)) {
throw new Error('Invalid session key for encryption.');
@ -348,7 +346,7 @@ export class Message {
}
symEncryptedPacket.packets = this.packets;
await symEncryptedPacket.encrypt(algorithm, sessionKeyData, streaming, config);
await symEncryptedPacket.encrypt(algorithm, sessionKeyData, config);
msg.packets.push(symEncryptedPacket);
symEncryptedPacket.packets = new PacketList(); // remove packets after encryption
@ -433,12 +431,11 @@ export class Message {
* @param {Array<module:type/keyid~KeyID>} [signingKeyIDs] - Array of key IDs to use for signing. Each signingKeyIDs[i] corresponds to privateKeys[i]
* @param {Date} [date] - Override the creation time of the signature
* @param {Array} [userIDs] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }]
* @param {Boolean} [streaming] - Whether to process data as a stream
* @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {Message} New message with signed content.
* @async
*/
async sign(privateKeys = [], signature = null, signingKeyIDs = [], date = new Date(), userIDs = [], streaming = false, config = defaultConfig) {
async sign(privateKeys = [], signature = null, signingKeyIDs = [], date = new Date(), userIDs = [], config = defaultConfig) {
const packetlist = new PacketList();
const literalDataPacket = this.packets.findPacket(enums.packet.literalData);
@ -488,7 +485,7 @@ export class Message {
});
packetlist.push(literalDataPacket);
packetlist.concat(await createSignaturePackets(literalDataPacket, privateKeys, signature, signingKeyIDs, date, userIDs, false, streaming, config));
packetlist.concat(await createSignaturePackets(literalDataPacket, privateKeys, signature, signingKeyIDs, date, userIDs, false, config));
return new Message(packetlist);
}
@ -521,49 +518,47 @@ export class Message {
* @param {Array<module:type/keyid~KeyID>} [signingKeyIDs] - Array of key IDs to use for signing. Each signingKeyIDs[i] corresponds to privateKeys[i]
* @param {Date} [date] - Override the creation time of the signature
* @param {Array} [userIDs] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }]
* @param {Boolean} [streaming] - Whether to process data as a stream
* @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {Signature} New detached signature of message content.
* @async
*/
async signDetached(privateKeys = [], signature = null, signingKeyIDs = [], date = new Date(), userIDs = [], streaming = false, config = defaultConfig) {
async signDetached(privateKeys = [], signature = null, signingKeyIds = [], date = new Date(), userIDs = [], config = defaultConfig) {
const literalDataPacket = this.packets.findPacket(enums.packet.literalData);
if (!literalDataPacket) {
throw new Error('No literal data packet to sign.');
}
return new Signature(await createSignaturePackets(literalDataPacket, privateKeys, signature, signingKeyIDs, date, userIDs, true, streaming, config));
return new Signature(await createSignaturePackets(literalDataPacket, privateKeys, signature, signingKeyIds, date, userIDs, true, config));
}
/**
* Verify message signatures
* @param {Array<Key>} keys - Array of keys to verify signatures
* @param {Date} [date] - Verify the signature against the given date, i.e. check signature creation time < date < expiration time
* @param {Boolean} [streaming] - Whether to process data as a stream
* @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {Array<{keyID: module:type/keyid~KeyID,
* signature: Promise<Signature>,
* verified: Promise<Boolean>}>} List of signer's keyID and validity of signatures.
* @async
*/
async verify(keys, date = new Date(), streaming, config = defaultConfig) {
async verify(keys, date = new Date(), config = defaultConfig) {
const msg = this.unwrapCompressed();
const literalDataList = msg.packets.filterByTag(enums.packet.literalData);
if (literalDataList.length !== 1) {
throw new Error('Can only verify message with one literal data packet.');
}
if (!streaming) {
if (stream.isArrayStream(msg.packets.stream)) {
msg.packets.concat(await stream.readToEnd(msg.packets.stream, _ => _));
}
const onePassSigList = msg.packets.filterByTag(enums.packet.onePassSignature).reverse();
const signatureList = msg.packets.filterByTag(enums.packet.signature);
if (streaming && onePassSigList.length && !signatureList.length && msg.packets.stream) {
if (onePassSigList.length && !signatureList.length && util.isStream(msg.packets.stream) && !stream.isArrayStream(msg.packets.stream)) {
await Promise.all(onePassSigList.map(async onePassSig => {
onePassSig.correspondingSig = new Promise((resolve, reject) => {
onePassSig.correspondingSigResolve = resolve;
onePassSig.correspondingSigReject = reject;
});
onePassSig.signatureData = stream.fromAsync(async () => (await onePassSig.correspondingSig).signatureData);
onePassSig.hashed = stream.readToEnd(await onePassSig.hash(onePassSig.signatureType, literalDataList[0], undefined, false, streaming));
onePassSig.hashed = stream.readToEnd(await onePassSig.hash(onePassSig.signatureType, literalDataList[0], undefined, false));
onePassSig.hashed.catch(() => {});
}));
msg.packets.stream = stream.transformPair(msg.packets.stream, async (readable, writable) => {
@ -584,9 +579,9 @@ export class Message {
await writer.abort(e);
}
});
return createVerificationObjects(onePassSigList, literalDataList, keys, date, false, streaming, config);
return createVerificationObjects(onePassSigList, literalDataList, keys, date, false, config);
}
return createVerificationObjects(signatureList, literalDataList, keys, date, false, streaming, config);
return createVerificationObjects(signatureList, literalDataList, keys, date, false, config);
}
/**
@ -600,14 +595,14 @@ export class Message {
* verified: Promise<Boolean>}>} List of signer's keyID and validity of signature.
* @async
*/
verifyDetached(signature, keys, date = new Date(), streaming, config = defaultConfig) {
verifyDetached(signature, keys, date = new Date(), config = defaultConfig) {
const msg = this.unwrapCompressed();
const literalDataList = msg.packets.filterByTag(enums.packet.literalData);
if (literalDataList.length !== 1) {
throw new Error('Can only verify message with one literal data packet.');
}
const signatureList = signature.packets;
return createVerificationObjects(signatureList, literalDataList, keys, date, true, undefined, config);
return createVerificationObjects(signatureList, literalDataList, keys, date, true, config);
}
/**
@ -717,13 +712,12 @@ export class Message {
* @param {Date} [date] - Override the creationtime of the signature
* @param {Array} [userIDs] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }]
* @param {Boolean} [detached] - Whether to create detached signature packets
* @param {Boolean} [streaming] - Whether to process data as a stream
* @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {PacketList} List of signature packets.
* @async
* @private
*/
export async function createSignaturePackets(literalDataPacket, privateKeys, signature = null, signingKeyIDs = [], date = new Date(), userIDs = [], detached = false, streaming = false, config = defaultConfig) {
export async function createSignaturePackets(literalDataPacket, privateKeys, signature = null, signingKeyIDs = [], date = new Date(), userIDs = [], detached = false, config = defaultConfig) {
const packetlist = new PacketList();
// If data packet was created from Uint8Array, use binary, otherwise use text
@ -736,7 +730,7 @@ export async function createSignaturePackets(literalDataPacket, privateKeys, sig
throw new Error('Need private key for signing');
}
const signingKey = await privateKey.getSigningKey(signingKeyIDs[i], date, userID, config);
return createSignaturePacket(literalDataPacket, privateKey, signingKey.keyPacket, { signatureType }, date, userID, detached, streaming, config);
return createSignaturePacket(literalDataPacket, privateKey, signingKey.keyPacket, { signatureType }, date, userID, detached, config);
})).then(signatureList => {
signatureList.forEach(signaturePacket => packetlist.push(signaturePacket));
});
@ -763,7 +757,7 @@ export async function createSignaturePackets(literalDataPacket, privateKeys, sig
* @async
* @private
*/
async function createVerificationObject(signature, literalDataList, keys, date = new Date(), detached = false, streaming = false, config = defaultConfig) {
async function createVerificationObject(signature, literalDataList, keys, date = new Date(), detached = false, config = defaultConfig) {
let primaryKey;
let signingKey;
let keyError;
@ -791,7 +785,7 @@ async function createVerificationObject(signature, literalDataList, keys, date =
if (keyError) {
throw keyError;
}
await signature.verify(signingKey.keyPacket, signature.signatureType, literalDataList[0], detached, streaming, config);
await signature.verify(signingKey.keyPacket, signature.signatureType, literalDataList[0], detached, config);
const sig = await signaturePacket;
if (sig.isExpired(date) || !(
sig.created >= signingKey.getCreationTime() &&
@ -837,11 +831,11 @@ async function createVerificationObject(signature, literalDataList, keys, date =
* @async
* @private
*/
export async function createVerificationObjects(signatureList, literalDataList, keys, date = new Date(), detached = false, streaming = false, config = defaultConfig) {
export async function createVerificationObjects(signatureList, literalDataList, keys, date = new Date(), detached = false, config = defaultConfig) {
return Promise.all(signatureList.filter(function(signature) {
return ['text', 'binary'].includes(enums.read(enums.signature, signature.signatureType));
}).map(async function(signature) {
return createVerificationObject(signature, literalDataList, keys, date, detached, streaming, config);
return createVerificationObject(signature, literalDataList, keys, date, detached, config);
}));
}

View File

@ -262,13 +262,13 @@ export function encrypt({ message, publicKeys, privateKeys, passwords, sessionKe
privateKeys = [];
}
if (privateKeys.length || signature) { // sign the message only if private keys or signature is specified
message = await message.sign(privateKeys, signature, signingKeyIDs, date, fromUserIDs, message.fromStream, config);
message = await message.sign(privateKeys, signature, signingKeyIDs, date, fromUserIDs, config);
}
message = message.compress(
await getPreferredAlgo('compression', publicKeys, date, toUserIDs, config),
config
);
message = await message.encrypt(publicKeys, passwords, sessionKey, wildcard, encryptionKeyIDs, date, toUserIDs, streaming, config);
message = await message.encrypt(publicKeys, passwords, sessionKey, wildcard, encryptionKeyIDs, date, toUserIDs, config);
const data = armor ? message.armor(config) : message.write();
return convertStream(data, streaming, armor ? 'utf8' : 'binary');
}).catch(onError.bind(null, 'Error encrypting message'));
@ -309,13 +309,13 @@ export function decrypt({ message, privateKeys, passwords, sessionKeys, publicKe
config = { ...defaultConfig, ...config };
checkMessage(message); publicKeys = toArray(publicKeys); privateKeys = toArray(privateKeys); passwords = toArray(passwords); sessionKeys = toArray(sessionKeys);
return message.decrypt(privateKeys, passwords, sessionKeys, streaming, config).then(async function(decrypted) {
return message.decrypt(privateKeys, passwords, sessionKeys, config).then(async function(decrypted) {
if (!publicKeys) {
publicKeys = [];
}
const result = {};
result.signatures = signature ? await decrypted.verifyDetached(signature, publicKeys, date, streaming, config) : await decrypted.verify(publicKeys, date, streaming, config);
result.signatures = signature ? await decrypted.verifyDetached(signature, publicKeys, date, config) : await decrypted.verify(publicKeys, date, config);
result.data = format === 'binary' ? decrypted.getLiteralData() : decrypted.getText();
result.filename = decrypted.getFilename();
linkStreams(result, message);
@ -358,12 +358,10 @@ export function sign({ message, privateKeys, armor = true, streaming = message &
return Promise.resolve().then(async function() {
let signature;
if (message instanceof CleartextMessage) {
signature = await message.sign(privateKeys, undefined, signingKeyIDs, date, fromUserIDs, config);
} else if (detached) {
signature = await message.signDetached(privateKeys, undefined, signingKeyIDs, date, fromUserIDs, message.fromStream, config);
if (detached) {
signature = await message.signDetached(privateKeys, undefined, signingKeyIDs, date, fromUserIDs, config);
} else {
signature = await message.sign(privateKeys, undefined, signingKeyIDs, date, fromUserIDs, message.fromStream, config);
signature = await message.sign(privateKeys, undefined, signingKeyIDs, date, fromUserIDs, config);
}
signature = armor ? signature.armor(config) : signature.write();
if (detached) {
@ -413,10 +411,10 @@ export function verify({ message, publicKeys, format = 'utf8', streaming = messa
return Promise.resolve().then(async function() {
const result = {};
if (message instanceof CleartextMessage) {
result.signatures = await message.verify(publicKeys, date, config);
if (signature) {
result.signatures = await message.verifyDetached(signature, publicKeys, date, config);
} else {
result.signatures = signature ? await message.verifyDetached(signature, publicKeys, date, streaming, config) : await message.verify(publicKeys, date, streaming, config);
result.signatures = await message.verify(publicKeys, date, config);
}
result.data = format === 'binary' ? message.getLiteralData() : message.getText();
if (streaming) linkStreams(result, message);

View File

@ -89,31 +89,29 @@ class AEADEncryptedDataPacket {
* Decrypt the encrypted payload.
* @param {String} sessionKeyAlgorithm - The session key's cipher algorithm e.g. 'aes128'
* @param {Uint8Array} key - The session key used to encrypt the payload
* @param {Boolean} streaming - Whether the top-level function will return a stream
* @throws {Error} if decryption was not successful
* @async
*/
async decrypt(sessionKeyAlgorithm, key, streaming) {
await this.packets.read(await this.crypt('decrypt', key, stream.clone(this.encrypted), streaming), allowedPackets, streaming);
async decrypt(sessionKeyAlgorithm, key) {
await this.packets.read(await this.crypt('decrypt', key, stream.clone(this.encrypted)), allowedPackets);
}
/**
* Encrypt the packet list payload.
* @param {String} sessionKeyAlgorithm - The session key's cipher algorithm e.g. 'aes128'
* @param {Uint8Array} key - The session key used to encrypt the payload
* @param {Boolean} streaming - Whether the top-level function will return a stream
* @param {Object} [config] - Full configuration, defaults to openpgp.config
* @throws {Error} if encryption was not successful
* @async
*/
async encrypt(sessionKeyAlgorithm, key, streaming, config = defaultConfig) {
async encrypt(sessionKeyAlgorithm, key, config = defaultConfig) {
this.cipherAlgo = enums.write(enums.symmetric, sessionKeyAlgorithm);
this.aeadAlgo = enums.write(enums.aead, this.aeadAlgorithm);
const mode = crypto.mode[enums.read(enums.aead, this.aeadAlgo)];
this.iv = await crypto.random.getRandomBytes(mode.ivLength); // generate new random IV
this.chunkSizeByte = config.aeadChunkSizeByte;
const data = this.packets.write();
this.encrypted = await this.crypt('encrypt', key, data, streaming);
this.encrypted = await this.crypt('encrypt', key, data);
}
/**
@ -121,11 +119,10 @@ class AEADEncryptedDataPacket {
* @param {encrypt|decrypt} fn - Whether to encrypt or decrypt
* @param {Uint8Array} key - The session key used to en/decrypt the payload
* @param {Uint8Array | ReadableStream<Uint8Array>} data - The data to en/decrypt
* @param {Boolean} streaming - Whether the top-level function will return a stream
* @returns {Uint8Array | ReadableStream<Uint8Array>}
* @async
*/
async crypt(fn, key, data, streaming) {
async crypt(fn, key, data) {
const cipher = enums.read(enums.symmetric, this.cipherAlgo);
const mode = crypto.mode[enums.read(enums.aead, this.aeadAlgo)];
const modeInstance = await mode(cipher, key);
@ -146,7 +143,7 @@ class AEADEncryptedDataPacket {
return stream.transformPair(data, async (readable, writable) => {
if (util.isStream(readable) !== 'array') {
const buffer = new stream.TransformStream({}, {
highWaterMark: streaming ? util.getHardwareConcurrency() * 2 ** (this.chunkSizeByte + 6) : Infinity,
highWaterMark: util.getHardwareConcurrency() * 2 ** (this.chunkSizeByte + 6),
size: array => array.length
});
stream.pipe(buffer.readable, writable);

View File

@ -117,7 +117,7 @@ export function supportsStreaming(tag_type) {
* @param {Function} callback - Function to call with the parsed packet
* @returns {Boolean} Returns false if the stream was empty and parsing is done, and true otherwise.
*/
export async function readPackets(input, streaming, callback) {
export async function readPackets(input, callback) {
const reader = stream.getReader(input);
let writer;
let callbackReturned;
@ -149,7 +149,7 @@ export async function readPackets(input, streaming, callback) {
const packetSupportsStreaming = supportsStreaming(tag);
let packet = null;
if (streaming && packetSupportsStreaming) {
if (packetSupportsStreaming) {
if (util.isStream(input) === 'array') {
const arrayStream = new stream.ArrayStream();
writer = stream.getWriter(arrayStream);

View File

@ -33,18 +33,18 @@ class PacketList extends Array {
* Reads a stream of binary data and interprets it as a list of packets.
* @param {Uint8Array | ReadableStream<Uint8Array>} bytes - A Uint8Array of bytes.
*/
async read(bytes, allowedPackets, streaming, config = defaultConfig) {
async read(bytes, allowedPackets, config = defaultConfig) {
this.stream = stream.transformPair(bytes, async (readable, writable) => {
const writer = stream.getWriter(writable);
try {
while (true) {
await writer.ready;
const done = await readPackets(readable, streaming, async parsed => {
const done = await readPackets(readable, async parsed => {
try {
const packet = newPacketFromTag(parsed.tag, allowedPackets);
packet.packets = new PacketList();
packet.fromStream = util.isStream(parsed.packet);
await packet.read(parsed.packet, config, streaming);
await packet.read(parsed.packet, config);
await writer.write(packet);
} catch (e) {
if (!config.tolerant || supportsStreaming(parsed.tag)) {

View File

@ -153,11 +153,10 @@ class SignaturePacket {
* @param {SecretKeyPacket} key - Private key used to sign the message.
* @param {Object} data - Contains packets to be signed.
* @param {Boolean} [detached] - Whether to create a detached signature
* @param {Boolean} [streaming] - Whether to process data as a stream
* @throws {Error} if signing failed
* @async
*/
async sign(key, data, detached = false, streaming = false) {
async sign(key, data, detached = false) {
const signatureType = enums.write(enums.signature, this.signatureType);
const publicKeyAlgorithm = enums.write(enums.publicKey, this.publicKeyAlgorithm);
const hashAlgorithm = enums.write(enums.hash, this.hashAlgorithm);
@ -183,7 +182,7 @@ class SignaturePacket {
const signed = async () => crypto.signature.sign(
publicKeyAlgorithm, hashAlgorithm, key.publicParams, key.privateParams, toHash, await stream.readToEnd(hash)
);
if (streaming) {
if (util.isStream(hash)) {
this.params = signed();
} else {
this.params = await signed();
@ -643,12 +642,9 @@ class SignaturePacket {
return util.concat([bytes, this.signatureData, this.calculateTrailer(data, detached)]);
}
async hash(signatureType, data, toHash, detached = false, streaming = true) {
async hash(signatureType, data, toHash, detached = false) {
const hashAlgorithm = enums.write(enums.hash, this.hashAlgorithm);
if (!toHash) toHash = this.toHash(signatureType, data, detached);
if (!streaming && util.isStream(toHash)) {
return stream.fromAsync(async () => this.hash(signatureType, data, await stream.readToEnd(toHash), detached));
}
return crypto.hash.digest(hashAlgorithm, toHash);
}
@ -659,12 +655,11 @@ class SignaturePacket {
* @param {module:enums.signature} signatureType - Expected signature type
* @param {String|Object} data - Data which on the signature applies
* @param {Boolean} [detached] - Whether to verify a detached signature
* @param {Boolean} [streaming] - Whether to process data as a stream
* @param {Object} [config] - Full configuration, defaults to openpgp.config
* @throws {Error} if signature validation failed
* @async
*/
async verify(key, signatureType, data, detached = false, streaming = false, config = defaultConfig) {
async verify(key, signatureType, data, detached = false, config = defaultConfig) {
const publicKeyAlgorithm = enums.write(enums.publicKey, this.publicKeyAlgorithm);
const hashAlgorithm = enums.write(enums.hash, this.hashAlgorithm);
@ -678,7 +673,6 @@ class SignaturePacket {
hash = await this.hashed;
} else {
toHash = this.toHash(signatureType, data, detached);
if (!streaming) toHash = await stream.readToEnd(toHash);
hash = await this.hash(signatureType, data, toHash);
}
hash = await stream.readToEnd(hash);

View File

@ -88,14 +88,13 @@ class SymEncryptedIntegrityProtectedDataPacket {
* Encrypt the payload in the packet.
* @param {String} sessionKeyAlgorithm - The selected symmetric encryption algorithm to be used e.g. 'aes128'
* @param {Uint8Array} key - The key of cipher blocksize length to be used
* @param {Boolean} streaming - Whether to set this.encrypted to a stream
* @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {Boolean}
* @async
*/
async encrypt(sessionKeyAlgorithm, key, streaming, config = defaultConfig) {
async encrypt(sessionKeyAlgorithm, key, config = defaultConfig) {
let bytes = this.packets.write();
if (!streaming) bytes = await stream.readToEnd(bytes);
if (stream.isArrayStream(bytes)) bytes = await stream.readToEnd(bytes);
const prefix = await crypto.getPrefixRandom(sessionKeyAlgorithm);
const mdc = new Uint8Array([0xD3, 0x14]); // modification detection code packet
@ -111,14 +110,13 @@ class SymEncryptedIntegrityProtectedDataPacket {
* Decrypts the encrypted data contained in the packet.
* @param {String} sessionKeyAlgorithm - The selected symmetric encryption algorithm to be used e.g. 'aes128'
* @param {Uint8Array} key - The key of cipher blocksize length to be used
* @param {Boolean} streaming - Whether to read this.encrypted as a stream
* @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {Boolean}
* @async
*/
async decrypt(sessionKeyAlgorithm, key, streaming, config = defaultConfig) {
async decrypt(sessionKeyAlgorithm, key, config = defaultConfig) {
let encrypted = stream.clone(this.encrypted);
if (!streaming) encrypted = await stream.readToEnd(encrypted);
if (stream.isArrayStream(encrypted)) encrypted = await stream.readToEnd(encrypted);
const decrypted = await crypto.mode.cfb.decrypt(sessionKeyAlgorithm, key, encrypted, new Uint8Array(crypto.cipher[sessionKeyAlgorithm].blockSize));
// there must be a modification detection code packet as the
@ -140,7 +138,7 @@ class SymEncryptedIntegrityProtectedDataPacket {
if (!util.isStream(encrypted) || !config.allowUnauthenticatedStream) {
packetbytes = await stream.readToEnd(packetbytes);
}
await this.packets.read(packetbytes, allowedPackets, streaming);
await this.packets.read(packetbytes, allowedPackets);
return true;
}
}

View File

@ -79,7 +79,7 @@ class SymmetricallyEncryptedDataPacket {
* @throws {Error} if decryption was not successful
* @async
*/
async decrypt(sessionKeyAlgorithm, key, streaming, config = defaultConfig) {
async decrypt(sessionKeyAlgorithm, key, config = defaultConfig) {
// If MDC errors are not being ignored, all missing MDC packets in symmetrically encrypted data should throw an error
if (!config.allowUnauthenticatedMessages) {
throw new Error('Message is not authenticated.');
@ -91,7 +91,7 @@ class SymmetricallyEncryptedDataPacket {
encrypted.subarray(2, crypto.cipher[sessionKeyAlgorithm].blockSize + 2)
);
await this.packets.read(decrypted, allowedPackets, streaming);
await this.packets.read(decrypted, allowedPackets);
}
/**
@ -103,7 +103,7 @@ class SymmetricallyEncryptedDataPacket {
* @throws {Error} if encryption was not successful
* @async
*/
async encrypt(algo, key, streaming, config = defaultConfig) {
async encrypt(algo, key, config = defaultConfig) {
const data = this.packets.write();
const prefix = await crypto.getPrefixRandom(algo);

View File

@ -221,7 +221,7 @@ module.exports = () => describe("Packet", function() {
const msg2 = new openpgp.PacketList();
try {
await enc.encrypt(algo, key, undefined, { ...openpgp.config, aeadChunkSizeByte: 0 });
await enc.encrypt(algo, key, { ...openpgp.config, aeadChunkSizeByte: 0 });
await msg2.read(msg.write(), allAllowedPackets);
await msg2[0].decrypt(algo, key);
expect(await openpgp.stream.readToEnd(msg2[0].packets[0].data)).to.deep.equal(literal.data);
@ -266,7 +266,7 @@ module.exports = () => describe("Packet", function() {
randomBytesStub.returns(iv);
try {
await enc.encrypt(algo, key, undefined, { ...openpgp.config, aeadChunkSizeByte: 14 });
await enc.encrypt(algo, key, { ...openpgp.config, aeadChunkSizeByte: 14 });
const data = msg.write();
expect(await openpgp.stream.readToEnd(openpgp.stream.clone(data))).to.deep.equal(packetBytes);
await msg2.read(data, allAllowedPackets);