Don't hack util.concatUint8Array() to handle Streams
Use util.concat() instead.
This commit is contained in:
parent
16ba26c298
commit
3475843d82
|
@ -169,7 +169,7 @@ Literal.prototype.write = function() {
|
||||||
const date = util.writeDate(this.date);
|
const date = util.writeDate(this.date);
|
||||||
const data = this.getBytes();
|
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;
|
export default Literal;
|
||||||
|
|
|
@ -86,19 +86,19 @@ List.prototype.write = function () {
|
||||||
if (bufferLength >= minLength) {
|
if (bufferLength >= minLength) {
|
||||||
const powerOf2 = Math.min(Math.log(bufferLength) / Math.LN2 | 0, 30);
|
const powerOf2 = Math.min(Math.log(bufferLength) / Math.LN2 | 0, 30);
|
||||||
const chunkSize = 2 ** powerOf2;
|
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)];
|
buffer = [bufferConcat.subarray(1 + chunkSize)];
|
||||||
bufferLength = buffer[0].length;
|
bufferLength = buffer[0].length;
|
||||||
return bufferConcat.subarray(0, 1 + chunkSize);
|
return bufferConcat.subarray(0, 1 + chunkSize);
|
||||||
}
|
}
|
||||||
}, () => util.concatUint8Array([packetParser.writeSimpleLength(bufferLength)].concat(buffer))));
|
}, () => util.concat([packetParser.writeSimpleLength(bufferLength)].concat(buffer))));
|
||||||
} else {
|
} else {
|
||||||
arr.push(packetParser.writeHeader(this[i].tag, packetbytes.length));
|
arr.push(packetParser.writeHeader(this[i].tag, packetbytes.length));
|
||||||
arr.push(packetbytes);
|
arr.push(packetbytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return util.concatUint8Array(arr);
|
return util.concat(arr);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -208,7 +208,7 @@ Signature.prototype.write = function () {
|
||||||
}
|
}
|
||||||
arr.push(this.signedHashValue);
|
arr.push(this.signedHashValue);
|
||||||
arr.push(this.signature);
|
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
|
// Add hashed subpackets
|
||||||
arr.push(this.write_all_sub_packets());
|
arr.push(this.write_all_sub_packets());
|
||||||
|
|
||||||
this.signatureData = util.concatUint8Array(arr);
|
this.signatureData = util.concat(arr);
|
||||||
|
|
||||||
const trailer = this.calculateTrailer();
|
const trailer = this.calculateTrailer();
|
||||||
|
|
||||||
|
@ -245,10 +245,10 @@ Signature.prototype.sign = async function (key, data) {
|
||||||
|
|
||||||
switch (this.version) {
|
switch (this.version) {
|
||||||
case 3:
|
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;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
toHash = util.concatUint8Array([this.toSign(signatureType, data), this.signatureData, trailer]);
|
toHash = util.concat([this.toSign(signatureType, data), this.signatureData, trailer]);
|
||||||
break;
|
break;
|
||||||
default: throw new Error('Version ' + this.version + ' of the signature is unsupported.');
|
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) {
|
if (this.revocationKeyClass !== null) {
|
||||||
bytes = new Uint8Array([this.revocationKeyClass, this.revocationKeyAlgorithm]);
|
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));
|
arr.push(write_sub_packet(sub.revocation_key, bytes));
|
||||||
}
|
}
|
||||||
if (!this.issuerKeyId.isNull() && this.issuerKeyVersion !== 5) {
|
if (!this.issuerKeyId.isNull() && this.issuerKeyVersion !== 5) {
|
||||||
|
@ -315,7 +315,7 @@ Signature.prototype.write_all_sub_packets = function () {
|
||||||
// 2 octets of value length
|
// 2 octets of value length
|
||||||
bytes.push(util.writeNumber(value.length, 2));
|
bytes.push(util.writeNumber(value.length, 2));
|
||||||
bytes.push(util.str_to_Uint8Array(name + value));
|
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));
|
arr.push(write_sub_packet(sub.notation_data, bytes));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -358,7 +358,7 @@ Signature.prototype.write_all_sub_packets = function () {
|
||||||
if (this.signatureTargetPublicKeyAlgorithm !== null) {
|
if (this.signatureTargetPublicKeyAlgorithm !== null) {
|
||||||
bytes = [new Uint8Array([this.signatureTargetPublicKeyAlgorithm, this.signatureTargetHashAlgorithm])];
|
bytes = [new Uint8Array([this.signatureTargetPublicKeyAlgorithm, this.signatureTargetHashAlgorithm])];
|
||||||
bytes.push(util.str_to_Uint8Array(this.signatureTargetHash));
|
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));
|
arr.push(write_sub_packet(sub.signature_target, bytes));
|
||||||
}
|
}
|
||||||
if (this.embeddedSignature !== null) {
|
if (this.embeddedSignature !== null) {
|
||||||
|
@ -366,7 +366,7 @@ Signature.prototype.write_all_sub_packets = function () {
|
||||||
}
|
}
|
||||||
if (this.issuerFingerprint !== null) {
|
if (this.issuerFingerprint !== null) {
|
||||||
bytes = [new Uint8Array([this.issuerKeyVersion]), this.issuerFingerprint];
|
bytes = [new Uint8Array([this.issuerKeyVersion]), this.issuerFingerprint];
|
||||||
bytes = util.concatUint8Array(bytes);
|
bytes = util.concat(bytes);
|
||||||
arr.push(write_sub_packet(sub.issuer_fingerprint, bytes));
|
arr.push(write_sub_packet(sub.issuer_fingerprint, bytes));
|
||||||
}
|
}
|
||||||
if (this.preferredAeadAlgorithms !== null) {
|
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));
|
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);
|
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(packet.writeSimpleLength(data.length + 1));
|
||||||
arr.push(new Uint8Array([type]));
|
arr.push(new Uint8Array([type]));
|
||||||
arr.push(data);
|
arr.push(data);
|
||||||
return util.concatUint8Array(arr);
|
return util.concat(arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// V4 signature sub packets
|
// V4 signature sub packets
|
||||||
|
@ -611,12 +611,12 @@ Signature.prototype.toSign = function (type, data) {
|
||||||
const bytes = packet.write();
|
const bytes = packet.write();
|
||||||
|
|
||||||
if (this.version === 4) {
|
if (this.version === 4) {
|
||||||
return util.concatUint8Array([this.toSign(t.key, data),
|
return util.concat([this.toSign(t.key, data),
|
||||||
new Uint8Array([tag]),
|
new Uint8Array([tag]),
|
||||||
util.writeNumber(bytes.length, 4),
|
util.writeNumber(bytes.length, 4),
|
||||||
bytes]);
|
bytes]);
|
||||||
} else if (this.version === 3) {
|
} else if (this.version === 3) {
|
||||||
return util.concatUint8Array([this.toSign(t.key, data),
|
return util.concat([this.toSign(t.key, data),
|
||||||
bytes]);
|
bytes]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -624,7 +624,7 @@ Signature.prototype.toSign = function (type, data) {
|
||||||
case t.subkey_binding:
|
case t.subkey_binding:
|
||||||
case t.subkey_revocation:
|
case t.subkey_revocation:
|
||||||
case t.key_binding:
|
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
|
key: data.bind
|
||||||
})]);
|
})]);
|
||||||
|
|
||||||
|
@ -653,7 +653,7 @@ Signature.prototype.calculateTrailer = function () {
|
||||||
return new Uint8Array(0);
|
return new Uint8Array(0);
|
||||||
}
|
}
|
||||||
const first = new Uint8Array([4, 0xFF]); //Version, ?
|
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(
|
this.verified = await crypto.signature.verify(
|
||||||
publicKeyAlgorithm, hashAlgorithm, mpi, key.params,
|
publicKeyAlgorithm, hashAlgorithm, mpi, key.params,
|
||||||
util.concatUint8Array([bytes, this.signatureData, trailer])
|
util.concat([bytes, this.signatureData, trailer])
|
||||||
);
|
);
|
||||||
|
|
||||||
return this.verified;
|
return this.verified;
|
||||||
|
|
|
@ -80,9 +80,9 @@ SymEncryptedAEADProtected.prototype.read = async function (bytes) {
|
||||||
*/
|
*/
|
||||||
SymEncryptedAEADProtected.prototype.write = function () {
|
SymEncryptedAEADProtected.prototype.write = function () {
|
||||||
if (config.aead_protect_version === 4) {
|
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]);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -77,7 +77,7 @@ SymEncryptedIntegrityProtected.prototype.read = async function (bytes) {
|
||||||
};
|
};
|
||||||
|
|
||||||
SymEncryptedIntegrityProtected.prototype.write = function () {
|
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 bytes = this.packets.write();
|
||||||
const prefixrandom = await crypto.getPrefixRandom(sessionKeyAlgorithm);
|
const prefixrandom = await crypto.getPrefixRandom(sessionKeyAlgorithm);
|
||||||
const repeat = new Uint8Array([prefixrandom[prefixrandom.length - 2], prefixrandom[prefixrandom.length - 1]]);
|
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
|
const mdc = new Uint8Array([0xD3, 0x14]); // modification detection code packet
|
||||||
|
|
||||||
let [tohash, tohashClone] = stream.tee(util.concatUint8Array([bytes, mdc]));
|
let [tohash, tohashClone] = stream.tee(util.concat([bytes, mdc]));
|
||||||
const hash = crypto.hash.sha1(util.concatUint8Array([prefix, tohashClone]));
|
const hash = crypto.hash.sha1(util.concat([prefix, tohashClone]));
|
||||||
tohash = util.concatUint8Array([tohash, hash]);
|
tohash = util.concat([tohash, hash]);
|
||||||
|
|
||||||
if (sessionKeyAlgorithm.substr(0, 3) === 'aes') { // AES optimizations. Native code for node, asmCrypto for browser.
|
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 {
|
} else {
|
||||||
this.encrypted = crypto.cfb.encrypt(prefixrandom, sessionKeyAlgorithm, tohash, key, false);
|
this.encrypted = crypto.cfb.encrypt(prefixrandom, sessionKeyAlgorithm, tohash, key, false);
|
||||||
this.encrypted = stream.subarray(this.encrypted, 0, prefix.length + tohash.length);
|
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 encryptedPrefix = await stream.readToEnd(stream.subarray(encryptedClone, 0, crypto.cipher[sessionKeyAlgorithm].blockSize + 2));
|
||||||
const prefix = crypto.cfb.mdc(sessionKeyAlgorithm, key, encryptedPrefix);
|
const prefix = crypto.cfb.mdc(sessionKeyAlgorithm, key, encryptedPrefix);
|
||||||
let [bytes, bytesClone] = stream.tee(stream.subarray(decrypted, 0, -20));
|
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)));
|
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)));
|
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);
|
key = new Buffer(key);
|
||||||
const iv = new Buffer(new Uint8Array(crypto.cipher[algo].blockSize));
|
const iv = new Buffer(new Uint8Array(crypto.cipher[algo].blockSize));
|
||||||
const cipherObj = new nodeCrypto.createCipheriv('aes-' + algo.substr(3, 3) + '-cfb', key, iv);
|
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);
|
return new Uint8Array(ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
23
src/util.js
23
src/util.js
|
@ -282,28 +282,29 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Concat a list of Uint8arrays or a list of Strings
|
* Concat a list of Uint8Arrays, Strings or Streams
|
||||||
* @param {Array<Uint8array|String>} Array of Uint8Arrays/Strings to concatenate
|
* The caller must not mix Uint8Arrays with Strings, but may mix Streams with non-Streams.
|
||||||
* @returns {Uint8array|String} Concatenated array
|
* @param {Array<Uint8array|String|ReadableStream>} Array of Uint8Arrays/Strings/Streams to concatenate
|
||||||
|
* @returns {Uint8array|String|ReadableStream} Concatenated array
|
||||||
*/
|
*/
|
||||||
concat: function (arrays) {
|
concat: function (list) {
|
||||||
if (util.isUint8Array(arrays[0])) {
|
if (list.some(util.isStream)) {
|
||||||
return util.concatUint8Array(arrays);
|
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
|
* @param {Array<Uint8array>} Array of Uint8Arrays to concatenate
|
||||||
* @returns {Uint8array} Concatenated array
|
* @returns {Uint8array} Concatenated array
|
||||||
*/
|
*/
|
||||||
concatUint8Array: function (arrays) {
|
concatUint8Array: function (arrays) {
|
||||||
let totalLength = 0;
|
let totalLength = 0;
|
||||||
for (let i = 0; i < arrays.length; i++) {
|
for (let i = 0; i < arrays.length; i++) {
|
||||||
if (util.isStream(arrays[i])) {
|
|
||||||
return stream.concat(arrays);
|
|
||||||
}
|
|
||||||
if (!util.isUint8Array(arrays[i])) {
|
if (!util.isUint8Array(arrays[i])) {
|
||||||
throw new Error('concatUint8Array: Data must be in the form of a Uint8Array');
|
throw new Error('concatUint8Array: Data must be in the form of a Uint8Array');
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user