Fix encoded length in unencrypted v5 secret key packets (#1278)
When unencrypted secret key packets are serialized, a 2-byte checksum is appended after the key material. According to rfc4880bis, these 2 bytes are not included in the length of the key material (this encoded length is a new addition of rfc4880bis, specific to v5 keys). We erroneously included them, causing other implementations to fail to parse unencrypted v5 private keys generated by OpenPGP.js.
This commit is contained in:
parent
2e19f1401c
commit
39aa742c7a
|
@ -205,17 +205,17 @@ class SecretKeyPacket extends PublicKeyPacket {
|
|||
if (!this.isDummy()) {
|
||||
if (!this.s2kUsage) {
|
||||
const algo = enums.write(enums.publicKey, this.algorithm);
|
||||
const cleartextParams = crypto.serializeParams(algo, this.privateParams);
|
||||
this.keyMaterial = util.concatUint8Array([
|
||||
cleartextParams,
|
||||
util.writeChecksum(cleartextParams)
|
||||
]);
|
||||
this.keyMaterial = crypto.serializeParams(algo, this.privateParams);
|
||||
}
|
||||
|
||||
if (this.version === 5) {
|
||||
arr.push(util.writeNumber(this.keyMaterial.length, 4));
|
||||
}
|
||||
arr.push(this.keyMaterial);
|
||||
|
||||
if (!this.s2kUsage) {
|
||||
arr.push(util.writeChecksum(this.keyMaterial));
|
||||
}
|
||||
}
|
||||
|
||||
return util.concatUint8Array(arr);
|
||||
|
|
|
@ -858,6 +858,41 @@ V+HOQJQxXJkVRYa3QrFUehiMzTeqqMdgC6ZqJy7+
|
|||
expect(secretKeyPacket2.publicParams).to.deep.equal(secretKeyPacket.publicParams);
|
||||
});
|
||||
|
||||
it('Writing of unencrypted v5 secret key packet', async function() {
|
||||
const originalV5KeysSetting = openpgp.config.v5Keys;
|
||||
openpgp.config.v5Keys = true;
|
||||
|
||||
try {
|
||||
const packet = new openpgp.SecretKeyPacket();
|
||||
|
||||
packet.privateParams = { key: new Uint8Array([1, 2, 3]) };
|
||||
packet.publicParams = { pubKey: new Uint8Array([4, 5, 6]) };
|
||||
packet.algorithm = "rsaSign";
|
||||
packet.isEncrypted = false;
|
||||
packet.s2kUsage = 0;
|
||||
|
||||
const written = packet.write();
|
||||
expect(written.length).to.equal(28);
|
||||
|
||||
/* The serialized length of private data */
|
||||
expect(written[17]).to.equal(0);
|
||||
expect(written[18]).to.equal(0);
|
||||
expect(written[19]).to.equal(0);
|
||||
expect(written[20]).to.equal(5);
|
||||
|
||||
/**
|
||||
* The private data
|
||||
*
|
||||
* The 2 bytes missing here are the length prefix of the MPI
|
||||
*/
|
||||
expect(written[23]).to.equal(1);
|
||||
expect(written[24]).to.equal(2);
|
||||
expect(written[25]).to.equal(3);
|
||||
} finally {
|
||||
openpgp.config.v5Keys = originalV5KeysSetting;
|
||||
}
|
||||
});
|
||||
|
||||
it('Writing and encryption of a secret key packet (CFB)', async function() {
|
||||
const rsa = openpgp.enums.publicKey.rsaEncryptSign;
|
||||
const { privateParams, publicParams } = await crypto.generateParams(rsa, 1024, 65537);
|
||||
|
|
Loading…
Reference in New Issue
Block a user