Don't hack util.concatUint8Array() to handle Streams

Use util.concat() instead.
This commit is contained in:
Daniel Huigens 2018-05-16 17:46:58 +02:00
parent 16ba26c298
commit 3475843d82
6 changed files with 42 additions and 41 deletions

View File

@ -169,7 +169,7 @@ Literal.prototype.write = function() {
const date = util.writeDate(this.date);
const data = this.getBytes();
return util.concatUint8Array([format, filename_length, filename, date, data]);
return util.concat([format, filename_length, filename, date, data]);
};
export default Literal;

View File

@ -86,19 +86,19 @@ List.prototype.write = function () {
if (bufferLength >= minLength) {
const powerOf2 = Math.min(Math.log(bufferLength) / Math.LN2 | 0, 30);
const chunkSize = 2 ** powerOf2;
const bufferConcat = util.concatUint8Array([packetParser.writePartialLength(powerOf2)].concat(buffer));
const bufferConcat = util.concat([packetParser.writePartialLength(powerOf2)].concat(buffer));
buffer = [bufferConcat.subarray(1 + chunkSize)];
bufferLength = buffer[0].length;
return bufferConcat.subarray(0, 1 + chunkSize);
}
}, () => util.concatUint8Array([packetParser.writeSimpleLength(bufferLength)].concat(buffer))));
}, () => util.concat([packetParser.writeSimpleLength(bufferLength)].concat(buffer))));
} else {
arr.push(packetParser.writeHeader(this[i].tag, packetbytes.length));
arr.push(packetbytes);
}
}
return util.concatUint8Array(arr);
return util.concat(arr);
};
/**

View File

@ -208,7 +208,7 @@ Signature.prototype.write = function () {
}
arr.push(this.signedHashValue);
arr.push(this.signature);
return util.concatUint8Array(arr);
return util.concat(arr);
};
/**
@ -237,7 +237,7 @@ Signature.prototype.sign = async function (key, data) {
// Add hashed subpackets
arr.push(this.write_all_sub_packets());
this.signatureData = util.concatUint8Array(arr);
this.signatureData = util.concat(arr);
const trailer = this.calculateTrailer();
@ -245,10 +245,10 @@ Signature.prototype.sign = async function (key, data) {
switch (this.version) {
case 3:
toHash = util.concatUint8Array([this.toSign(signatureType, data), new Uint8Array([signatureType]), util.writeDate(this.created)]);
toHash = util.concat([this.toSign(signatureType, data), new Uint8Array([signatureType]), util.writeDate(this.created)]);
break;
case 4:
toHash = util.concatUint8Array([this.toSign(signatureType, data), this.signatureData, trailer]);
toHash = util.concat([this.toSign(signatureType, data), this.signatureData, trailer]);
break;
default: throw new Error('Version ' + this.version + ' of the signature is unsupported.');
}
@ -299,7 +299,7 @@ Signature.prototype.write_all_sub_packets = function () {
}
if (this.revocationKeyClass !== null) {
bytes = new Uint8Array([this.revocationKeyClass, this.revocationKeyAlgorithm]);
bytes = util.concatUint8Array([bytes, this.revocationKeyFingerprint]);
bytes = util.concat([bytes, this.revocationKeyFingerprint]);
arr.push(write_sub_packet(sub.revocation_key, bytes));
}
if (!this.issuerKeyId.isNull() && this.issuerKeyVersion !== 5) {
@ -315,7 +315,7 @@ Signature.prototype.write_all_sub_packets = function () {
// 2 octets of value length
bytes.push(util.writeNumber(value.length, 2));
bytes.push(util.str_to_Uint8Array(name + value));
bytes = util.concatUint8Array(bytes);
bytes = util.concat(bytes);
arr.push(write_sub_packet(sub.notation_data, bytes));
});
}
@ -358,7 +358,7 @@ Signature.prototype.write_all_sub_packets = function () {
if (this.signatureTargetPublicKeyAlgorithm !== null) {
bytes = [new Uint8Array([this.signatureTargetPublicKeyAlgorithm, this.signatureTargetHashAlgorithm])];
bytes.push(util.str_to_Uint8Array(this.signatureTargetHash));
bytes = util.concatUint8Array(bytes);
bytes = util.concat(bytes);
arr.push(write_sub_packet(sub.signature_target, bytes));
}
if (this.embeddedSignature !== null) {
@ -366,7 +366,7 @@ Signature.prototype.write_all_sub_packets = function () {
}
if (this.issuerFingerprint !== null) {
bytes = [new Uint8Array([this.issuerKeyVersion]), this.issuerFingerprint];
bytes = util.concatUint8Array(bytes);
bytes = util.concat(bytes);
arr.push(write_sub_packet(sub.issuer_fingerprint, bytes));
}
if (this.preferredAeadAlgorithms !== null) {
@ -374,10 +374,10 @@ Signature.prototype.write_all_sub_packets = function () {
arr.push(write_sub_packet(sub.preferred_aead_algorithms, bytes));
}
const result = util.concatUint8Array(arr);
const result = util.concat(arr);
const length = util.writeNumber(result.length, 2);
return util.concatUint8Array([length, result]);
return util.concat([length, result]);
};
/**
@ -394,7 +394,7 @@ function write_sub_packet(type, data) {
arr.push(packet.writeSimpleLength(data.length + 1));
arr.push(new Uint8Array([type]));
arr.push(data);
return util.concatUint8Array(arr);
return util.concat(arr);
}
// V4 signature sub packets
@ -611,12 +611,12 @@ Signature.prototype.toSign = function (type, data) {
const bytes = packet.write();
if (this.version === 4) {
return util.concatUint8Array([this.toSign(t.key, data),
return util.concat([this.toSign(t.key, data),
new Uint8Array([tag]),
util.writeNumber(bytes.length, 4),
bytes]);
} else if (this.version === 3) {
return util.concatUint8Array([this.toSign(t.key, data),
return util.concat([this.toSign(t.key, data),
bytes]);
}
break;
@ -624,7 +624,7 @@ Signature.prototype.toSign = function (type, data) {
case t.subkey_binding:
case t.subkey_revocation:
case t.key_binding:
return util.concatUint8Array([this.toSign(t.key, data), this.toSign(t.key, {
return util.concat([this.toSign(t.key, data), this.toSign(t.key, {
key: data.bind
})]);
@ -653,7 +653,7 @@ Signature.prototype.calculateTrailer = function () {
return new Uint8Array(0);
}
const first = new Uint8Array([4, 0xFF]); //Version, ?
return util.concatUint8Array([first, util.writeNumber(this.signatureData.length, 4)]);
return util.concat([first, util.writeNumber(this.signatureData.length, 4)]);
};
@ -700,7 +700,7 @@ Signature.prototype.verify = async function (key, data) {
this.verified = await crypto.signature.verify(
publicKeyAlgorithm, hashAlgorithm, mpi, key.params,
util.concatUint8Array([bytes, this.signatureData, trailer])
util.concat([bytes, this.signatureData, trailer])
);
return this.verified;

View File

@ -80,9 +80,9 @@ SymEncryptedAEADProtected.prototype.read = async function (bytes) {
*/
SymEncryptedAEADProtected.prototype.write = function () {
if (config.aead_protect_version === 4) {
return util.concatUint8Array([new Uint8Array([this.version, this.cipherAlgo, this.aeadAlgo, this.chunkSizeByte]), this.iv, this.encrypted]);
return util.concat([new Uint8Array([this.version, this.cipherAlgo, this.aeadAlgo, this.chunkSizeByte]), this.iv, this.encrypted]);
}
return util.concatUint8Array([new Uint8Array([this.version]), this.iv, this.encrypted]);
return util.concat([new Uint8Array([this.version]), this.iv, this.encrypted]);
};
/**

View File

@ -77,7 +77,7 @@ SymEncryptedIntegrityProtected.prototype.read = async function (bytes) {
};
SymEncryptedIntegrityProtected.prototype.write = function () {
return util.concatUint8Array([new Uint8Array([VERSION]), this.encrypted]);
return util.concat([new Uint8Array([VERSION]), this.encrypted]);
};
/**
@ -91,15 +91,15 @@ SymEncryptedIntegrityProtected.prototype.encrypt = async function (sessionKeyAlg
const bytes = this.packets.write();
const prefixrandom = await crypto.getPrefixRandom(sessionKeyAlgorithm);
const repeat = new Uint8Array([prefixrandom[prefixrandom.length - 2], prefixrandom[prefixrandom.length - 1]]);
const prefix = util.concatUint8Array([prefixrandom, repeat]);
const prefix = util.concat([prefixrandom, repeat]);
const mdc = new Uint8Array([0xD3, 0x14]); // modification detection code packet
let [tohash, tohashClone] = stream.tee(util.concatUint8Array([bytes, mdc]));
const hash = crypto.hash.sha1(util.concatUint8Array([prefix, tohashClone]));
tohash = util.concatUint8Array([tohash, hash]);
let [tohash, tohashClone] = stream.tee(util.concat([bytes, mdc]));
const hash = crypto.hash.sha1(util.concat([prefix, tohashClone]));
tohash = util.concat([tohash, hash]);
if (sessionKeyAlgorithm.substr(0, 3) === 'aes') { // AES optimizations. Native code for node, asmCrypto for browser.
this.encrypted = aesEncrypt(sessionKeyAlgorithm, util.concatUint8Array([prefix, tohash]), key);
this.encrypted = aesEncrypt(sessionKeyAlgorithm, util.concat([prefix, tohash]), key);
} else {
this.encrypted = crypto.cfb.encrypt(prefixrandom, sessionKeyAlgorithm, tohash, key, false);
this.encrypted = stream.subarray(this.encrypted, 0, prefix.length + tohash.length);
@ -130,7 +130,7 @@ SymEncryptedIntegrityProtected.prototype.decrypt = async function (sessionKeyAlg
const encryptedPrefix = await stream.readToEnd(stream.subarray(encryptedClone, 0, crypto.cipher[sessionKeyAlgorithm].blockSize + 2));
const prefix = crypto.cfb.mdc(sessionKeyAlgorithm, key, encryptedPrefix);
let [bytes, bytesClone] = stream.tee(stream.subarray(decrypted, 0, -20));
const tohash = util.concatUint8Array([prefix, bytes]);
const tohash = util.concat([prefix, bytes]);
this.hash = util.Uint8Array_to_str(await stream.readToEnd(crypto.hash.sha1(tohash)));
const mdc = util.Uint8Array_to_str(await stream.readToEnd(stream.subarray(decryptedClone, -20)));
@ -176,7 +176,7 @@ function nodeEncrypt(algo, prefix, pt, key) {
key = new Buffer(key);
const iv = new Buffer(new Uint8Array(crypto.cipher[algo].blockSize));
const cipherObj = new nodeCrypto.createCipheriv('aes-' + algo.substr(3, 3) + '-cfb', key, iv);
const ct = cipherObj.update(new Buffer(util.concatUint8Array([prefix, pt])));
const ct = cipherObj.update(new Buffer(util.concat([prefix, pt])));
return new Uint8Array(ct);
}

View File

@ -282,28 +282,29 @@ export default {
},
/**
* Concat a list of Uint8arrays or a list of Strings
* @param {Array<Uint8array|String>} Array of Uint8Arrays/Strings to concatenate
* @returns {Uint8array|String} Concatenated array
* Concat a list of Uint8Arrays, Strings or Streams
* The caller must not mix Uint8Arrays with Strings, but may mix Streams with non-Streams.
* @param {Array<Uint8array|String|ReadableStream>} Array of Uint8Arrays/Strings/Streams to concatenate
* @returns {Uint8array|String|ReadableStream} Concatenated array
*/
concat: function (arrays) {
if (util.isUint8Array(arrays[0])) {
return util.concatUint8Array(arrays);
concat: function (list) {
if (list.some(util.isStream)) {
return stream.concat(list);
}
return arrays.join('');
if (util.isUint8Array(list[0])) {
return util.concatUint8Array(list);
}
return list.join('');
},
/**
* Concat Uint8arrays
* Concat Uint8Arrays
* @param {Array<Uint8array>} Array of Uint8Arrays to concatenate
* @returns {Uint8array} Concatenated array
*/
concatUint8Array: function (arrays) {
let totalLength = 0;
for (let i = 0; i < arrays.length; i++) {
if (util.isStream(arrays[i])) {
return stream.concat(arrays);
}
if (!util.isUint8Array(arrays[i])) {
throw new Error('concatUint8Array: Data must be in the form of a Uint8Array');
}