From 151ae759590754c4126049b5792b94c9a797198f Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Tue, 5 Nov 2024 12:19:32 +0100 Subject: [PATCH] Update to draft-ietf-openpgp-persistent-symmetric-keys-00 --- src/crypto/crypto.js | 125 ++++++++++++++++------------------ src/crypto/public_key/hmac.js | 5 +- src/crypto/signature.js | 13 ++-- src/enums.js | 4 +- src/key/helper.js | 5 +- src/key/private_key.js | 4 +- src/openpgp.js | 2 +- src/packet/public_key.js | 7 +- src/packet/secret_key.js | 4 +- src/type/short_byte_string.js | 32 --------- test/general/key.js | 14 ++-- test/general/packet.js | 22 +++--- 12 files changed, 99 insertions(+), 138 deletions(-) delete mode 100644 src/type/short_byte_string.js diff --git a/src/crypto/crypto.js b/src/crypto/crypto.js index 293ab286..793a7a66 100644 --- a/src/crypto/crypto.js +++ b/src/crypto/crypto.js @@ -28,9 +28,7 @@ import mode from './mode'; import { getRandomBytes } from './random'; import { getCipherParams } from './cipher'; import ECDHSymkey from '../type/ecdh_symkey'; -import ShortByteString from '../type/short_byte_string'; import hash from './hash'; -import config from '../config'; import KDFParams from '../type/kdf_params'; import { SymAlgoEnum, AEADEnum, HashEnum } from '../type/enum'; import enums from '../enums'; @@ -85,16 +83,16 @@ export async function publicKeyEncrypt(keyAlgo, symmetricAlgo, publicParams, pri if (!privateParams) { throw new Error('Cannot encrypt with symmetric key missing private parameters'); } - const { cipher: algo } = publicParams; - const algoValue = algo.getValue(); + const { symAlgo, aeadMode } = publicParams; const { keyMaterial } = privateParams; - const aeadMode = config.preferredAEADAlgorithm; - const mode = getAEADMode(config.preferredAEADAlgorithm); + + const mode = getAEADMode(aeadMode.getValue()); const { ivLength } = mode; const iv = getRandomBytes(ivLength); - const modeInstance = await mode(algoValue, keyMaterial); - const c = await modeInstance.encrypt(data, iv, new Uint8Array()); - return { aeadMode: new AEADEnum(aeadMode), iv, c: new ShortByteString(c) }; + const modeInstance = await mode(symAlgo.getValue(), keyMaterial); + const ciphertext = await modeInstance.encrypt(data, iv, new Uint8Array()); + const ivAndCiphertext = util.concatUint8Array([iv, ciphertext]); + return { ivAndCiphertext }; } case enums.publicKey.pqc_mlkem_x25519: { const { eccPublicKey, mlkemPublicKey } = publicParams; @@ -155,15 +153,17 @@ export async function publicKeyDecrypt(keyAlgo, publicKeyParams, privateKeyParam keyAlgo, ephemeralPublicKey, C.wrappedKey, A, k); } case enums.publicKey.aead: { - const { cipher: algo } = publicKeyParams; - const algoValue = algo.getValue(); + const { symAlgo, aeadMode } = publicKeyParams; const { keyMaterial } = privateKeyParams; - const { aeadMode, iv, c } = sessionKeyParams; + const { ivAndCiphertext } = sessionKeyParams; const mode = getAEADMode(aeadMode.getValue()); - const modeInstance = await mode(algoValue, keyMaterial); - return modeInstance.decrypt(c.data, iv, new Uint8Array()); + const { ivLength } = mode; + const modeInstance = await mode(symAlgo.getValue(), keyMaterial); + const iv = ivAndCiphertext.subarray(0, ivLength); + const ciphertext = ivAndCiphertext.subarray(ivLength); + return modeInstance.decrypt(ciphertext, iv, new Uint8Array()); } case enums.publicKey.pqc_mlkem_x25519: { const { eccSecretKey, mlkemSecretKey } = privateKeyParams; @@ -235,12 +235,16 @@ export function parsePublicKeyParams(algo, bytes) { const A = util.readExactSubarray(bytes, read, read + getCurvePayloadSize(algo)); read += A.length; return { read, publicParams: { A } }; } - case enums.publicKey.hmac: + case enums.publicKey.hmac: { + const hashAlgo = new HashEnum(); read += hashAlgo.read(bytes); + const fpSeed = bytes.subarray(read, read + 32); read += 32; + return { read: read, publicParams: { hashAlgo, fpSeed } }; + } case enums.publicKey.aead: { - const algo = new SymAlgoEnum(); read += algo.read(bytes); - const digestLength = hash.getHashByteLength(enums.hash.sha256); - const digest = bytes.subarray(read, read + digestLength); read += digestLength; - return { read: read, publicParams: { cipher: algo, digest } }; + const symAlgo = new SymAlgoEnum(); read += symAlgo.read(bytes); + const aeadMode = new AEADEnum(); read += aeadMode.read(bytes.subarray(read)); + const fpSeed = bytes.subarray(read, read + 32); read += 32; + return { read: read, publicParams: { symAlgo, aeadMode, fpSeed } }; } case enums.publicKey.pqc_mlkem_x25519: { const eccPublicKey = util.readExactSubarray(bytes, read, read + getCurvePayloadSize(enums.publicKey.x25519)); read += eccPublicKey.length; @@ -310,18 +314,16 @@ export async function parsePrivateKeyParams(algo, bytes, publicParams) { return { read, privateParams: { k } }; } case enums.publicKey.hmac: { - const { cipher: algo } = publicParams; - const keySize = hash.getHashByteLength(algo.getValue()); - const hashSeed = bytes.subarray(read, read + 32); read += 32; + const { hashAlgo } = publicParams; + const keySize = hash.getHashByteLength(hashAlgo.getValue()); const keyMaterial = bytes.subarray(read, read + keySize); read += keySize; - return { read, privateParams: { hashSeed, keyMaterial } }; + return { read, privateParams: { keyMaterial } }; } case enums.publicKey.aead: { - const { cipher: algo } = publicParams; - const hashSeed = bytes.subarray(read, read + 32); read += 32; - const { keySize } = getCipherParams(algo.getValue()); + const { symAlgo } = publicParams; + const { keySize } = getCipherParams(symAlgo.getValue()); const keyMaterial = bytes.subarray(read, read + keySize); read += keySize; - return { read, privateParams: { hashSeed, keyMaterial } }; + return { read, privateParams: { keyMaterial } }; } case enums.publicKey.pqc_mlkem_x25519: { const eccSecretKey = util.readExactSubarray(bytes, read, read + getCurvePayloadSize(enums.publicKey.x25519)); read += eccSecretKey.length; @@ -385,18 +387,13 @@ export function parseEncSessionKeyParams(algo, bytes) { return { ephemeralPublicKey, C }; } // Algorithm-Specific Fields for symmetric AEAD encryption: - // - AEAD algorithm // - Starting initialization vector - // - Symmetric key encryption of "m" dependent on cipher and AEAD mode prefixed with a one-octet length + // - Symmetric key encryption of "m" using cipher and AEAD mode // - An authentication tag generated by the AEAD mode. case enums.publicKey.aead: { - const aeadMode = new AEADEnum(); read += aeadMode.read(bytes.subarray(read)); - const { ivLength } = getAEADMode(aeadMode.getValue()); + const ivAndCiphertext = bytes; - const iv = bytes.subarray(read, read + ivLength); read += ivLength; - const c = new ShortByteString(); read += c.read(bytes.subarray(read)); - - return { aeadMode, iv, c }; + return { ivAndCiphertext }; } case enums.publicKey.pqc_mlkem_x25519: { const eccCipherText = util.readExactSubarray(bytes, read, read + getCurvePayloadSize(enums.publicKey.x25519)); read += eccCipherText.length; @@ -451,10 +448,11 @@ export function serializeParams(algo, params) { * @param {Integer} bits - Bit length for RSA keys * @param {module:type/oid} oid - Object identifier for ECC keys * @param {module:enums.symmetric|enums.hash} symmetric - Hash or cipher algorithm for symmetric keys + * @param {module:enums.aead} aeadMode - AEAD mode for AEAD keys * @returns {Promise<{ publicParams: {Object}, privateParams: {Object} }>} The parameters referenced by name. * @async */ -export async function generateParams(algo, bits, oid, symmetric) { +export async function generateParams(algo, bits, oid, symmetric, aeadMode) { switch (algo) { case enums.publicKey.rsaEncrypt: case enums.publicKey.rsaEncryptSign: @@ -496,11 +494,30 @@ export async function generateParams(algo, bits, oid, symmetric) { })); case enums.publicKey.hmac: { const keyMaterial = await publicKey.hmac.generate(symmetric); - return createSymmetricParams(keyMaterial, new HashEnum(symmetric)); + const fpSeed = getRandomBytes(32); + return { + privateParams: { + keyMaterial + }, + publicParams: { + hashAlgo: new HashEnum(symmetric), + fpSeed + } + }; } case enums.publicKey.aead: { const keyMaterial = generateSessionKey(symmetric); - return createSymmetricParams(keyMaterial, new SymAlgoEnum(symmetric)); + const fpSeed = getRandomBytes(32); + return { + privateParams: { + keyMaterial + }, + publicParams: { + symAlgo: new SymAlgoEnum(symmetric), + aeadMode: new AEADEnum(aeadMode), + fpSeed + } + }; } case enums.publicKey.pqc_mlkem_x25519: return publicKey.postQuantum.kem.generate(algo).then(({ eccSecretKey, eccPublicKey, mlkemSeed, mlkemSecretKey, mlkemPublicKey }) => ({ @@ -520,21 +537,6 @@ export async function generateParams(algo, bits, oid, symmetric) { } } -async function createSymmetricParams(key, algo) { - const seed = getRandomBytes(32); - const bindingHash = await hash.sha256(seed); - return { - privateParams: { - hashSeed: seed, - keyMaterial: key - }, - publicParams: { - cipher: algo, - digest: bindingHash - } - }; -} - /** * Validate algorithm-specific key parameters * @param {module:enums.publicKey} algo - The public key algorithm @@ -589,20 +591,9 @@ export async function validateParams(algo, publicParams, privateParams) { const { k } = privateParams; return publicKey.elliptic.ecdhX.validateParams(algo, A, k); } - case enums.publicKey.hmac: { - const { cipher: algo, digest } = publicParams; - const { hashSeed, keyMaterial } = privateParams; - const keySize = hash.getHashByteLength(algo.getValue()); - return keySize === keyMaterial.length && - util.equalsUint8Array(digest, await hash.sha256(hashSeed)); - } - case enums.publicKey.aead: { - const { cipher: algo, digest } = publicParams; - const { hashSeed, keyMaterial } = privateParams; - const { keySize } = getCipherParams(algo.getValue()); - return keySize === keyMaterial.length && - util.equalsUint8Array(digest, await hash.sha256(hashSeed)); - } + case enums.publicKey.hmac: + case enums.publicKey.aead: + throw new Error('Persistent symmetric keys must be encrypted using AEAD'); case enums.publicKey.pqc_mlkem_x25519: { const { eccSecretKey, mlkemSeed } = privateParams; const { eccPublicKey, mlkemPublicKey } = publicParams; diff --git a/src/crypto/public_key/hmac.js b/src/crypto/public_key/hmac.js index f74f20d7..2f8b680b 100644 --- a/src/crypto/public_key/hmac.js +++ b/src/crypto/public_key/hmac.js @@ -1,5 +1,6 @@ import enums from '../../enums'; import util from '../../util'; +import hash from '../hash'; const supportedHashAlgos = new Set([enums.hash.sha1, enums.hash.sha256, enums.hash.sha512]); @@ -11,12 +12,14 @@ export async function generate(hashAlgo) { throw new Error('Unsupported hash algorithm.'); } const hashName = enums.read(enums.webHash, hashAlgo); + const keySize = hash.getHashByteLength(hashAlgo); const crypto = webCrypto || nodeCrypto.webcrypto.subtle; const key = await crypto.generateKey( { name: 'HMAC', - hash: { name: hashName } + hash: { name: hashName }, + length: keySize * 8 }, true, ['sign', 'verify'] diff --git a/src/crypto/signature.js b/src/crypto/signature.js index 9b7d6a89..08af7c5b 100644 --- a/src/crypto/signature.js +++ b/src/crypto/signature.js @@ -6,7 +6,6 @@ import publicKey from './public_key'; import enums from '../enums'; import util from '../util'; -import ShortByteString from '../type/short_byte_string'; import { UnsupportedError } from '../packet/packet'; /** @@ -67,7 +66,7 @@ export function parseSignatureParams(algo, signature) { return { read, signatureParams: { RS } }; } case enums.publicKey.hmac: { - const mac = new ShortByteString(); read += mac.read(signature.subarray(read)); + const mac = signature; read += signature.length; return { read, signatureParams: { mac } }; } case enums.publicKey.pqc_mldsa_ed25519: { @@ -136,9 +135,9 @@ export async function verify(algo, hashAlgo, signature, publicParams, privatePar if (!privateParams) { throw new Error('Cannot verify HMAC signature with symmetric key missing private parameters'); } - const { cipher: algo } = publicParams; + const { hashAlgo } = publicParams; const { keyMaterial } = privateParams; - return publicKey.hmac.verify(algo.getValue(), keyMaterial, signature.mac.data, hashed); + return publicKey.hmac.verify(hashAlgo.getValue(), keyMaterial, signature.mac, hashed); } case enums.publicKey.pqc_mldsa_ed25519: { const { eccPublicKey, mldsaPublicKey } = publicParams; @@ -200,10 +199,10 @@ export async function sign(algo, hashAlgo, publicKeyParams, privateKeyParams, da return publicKey.elliptic.eddsa.sign(algo, hashAlgo, data, A, seed, hashed); } case enums.publicKey.hmac: { - const { cipher: algo } = publicKeyParams; + const { hashAlgo } = publicKeyParams; const { keyMaterial } = privateKeyParams; - const mac = await publicKey.hmac.sign(algo.getValue(), keyMaterial, hashed); - return { mac: new ShortByteString(mac) }; + const mac = await publicKey.hmac.sign(hashAlgo.getValue(), keyMaterial, hashed); + return { mac }; } case enums.publicKey.pqc_mldsa_ed25519: { const { eccPublicKey } = publicKeyParams; diff --git a/src/enums.js b/src/enums.js index e53f6667..b1c75ae7 100644 --- a/src/enums.js +++ b/src/enums.js @@ -102,9 +102,9 @@ export default { pqc_mldsa_ed25519: 107, /** Persistent symmetric keys: encryption algorithm */ - aead: 100, + aead: 128, /** Persistent symmetric keys: authentication algorithm */ - hmac: 101 + hmac: 129 }, /** {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC4880, section 9.2} diff --git a/src/key/helper.js b/src/key/helper.js index ba08bb19..50088701 100644 --- a/src/key/helper.js +++ b/src/key/helper.js @@ -17,7 +17,7 @@ export async function generateSecretSubkey(options, config) { const secretSubkeyPacket = new SecretSubkeyPacket(options.date, config); secretSubkeyPacket.packets = null; secretSubkeyPacket.algorithm = enums.write(enums.publicKey, options.algorithm); - await secretSubkeyPacket.generate(options.rsaBits, options.curve, options.symmetric); + await secretSubkeyPacket.generate(options.rsaBits, options.curve, options.symmetric, config.preferredAEADAlgorithm); await secretSubkeyPacket.computeFingerprintAndKeyID(); return secretSubkeyPacket; } @@ -26,7 +26,7 @@ export async function generateSecretKey(options, config) { const secretKeyPacket = new SecretKeyPacket(options.date, config); secretKeyPacket.packets = null; secretKeyPacket.algorithm = enums.write(enums.publicKey, options.algorithm); - await secretKeyPacket.generate(options.rsaBits, options.curve, options.symmetric); + await secretKeyPacket.generate(options.rsaBits, options.curve, options.symmetric, config.preferredAEADAlgorithm); await secretKeyPacket.computeFingerprintAndKeyID(); return secretKeyPacket; } @@ -506,6 +506,7 @@ export function validateDecryptionKeyPacket(keyPacket, signature, config) { case enums.publicKey.ecdh: case enums.publicKey.x25519: case enums.publicKey.x448: + case enums.publicKey.aead: case enums.publicKey.pqc_mlkem_x25519: { const isValidSigningKeyPacket = !signature.keyFlags || (signature.keyFlags[0] & enums.keyFlags.signData) !== 0; if (isValidSigningKeyPacket && config.allowInsecureDecryptionWithSigningKeys) { diff --git a/src/key/private_key.js b/src/key/private_key.js index 2a9b2f29..29e0cb7f 100644 --- a/src/key/private_key.js +++ b/src/key/private_key.js @@ -50,7 +50,7 @@ class PrivateKey extends PublicKey { switch (keyPacket.constructor.tag) { case enums.packet.secretKey: { if (keyPacket.algorithm === enums.publicKey.aead || keyPacket.algorithm === enums.publicKey.hmac) { - throw new Error('Cannot create public key from symmetric private'); + throw new Error('Cannot create public key from symmetric private key'); } const pubKeyPacket = PublicKeyPacket.fromSecretKeyPacket(keyPacket); packetlist.push(pubKeyPacket); @@ -238,7 +238,7 @@ class PrivateKey extends PublicKey { * @param {String} options.curve (optional) Elliptic curve for ECC keys * @param {Integer} options.rsaBits (optional) Number of bits for RSA subkeys * @param {String} options.symmetricCipher (optional) Symmetric algorithm for persistent symmetric aead keys - * @param {String} options.symmetricHash (optional)Hash lgorithm for persistent symmetric hmac keys + * @param {String} options.symmetricHash (optional) Hash algorithm for persistent symmetric hmac keys * @param {Number} options.keyExpirationTime (optional) Number of seconds from the key creation time after which the key expires * @param {Date} options.date (optional) Override the creation date of the key and the key signatures * @param {Boolean} options.sign (optional) Indicates whether the subkey should sign rather than encrypt. Defaults to false diff --git a/src/openpgp.js b/src/openpgp.js index 7073166c..672504ff 100644 --- a/src/openpgp.js +++ b/src/openpgp.js @@ -45,7 +45,7 @@ import { checkKeyRequirements } from './key/helper'; * curve25519Legacy (default), nistP256, nistP384, nistP521, secp256k1, * brainpoolP256r1, brainpoolP384r1, or brainpoolP512r1 * @param {String} options.symmetricCipher (optional) Symmetric algorithm for persistent symmetric aead keys -* @param {String} options.symmetricHash (optional)Hash lgorithm for persistent symmetric hmac keys +* @param {String} options.symmetricHash (optional) Hash algorithm for persistent symmetric hmac keys * @param {Date} [options.date=current date] - Override the creation date of the key and the key signatures * @param {Number} [options.keyExpirationTime=0 (never expires)] - Number of seconds from the key creation time after which the key expires * @param {Array} [options.subkeys=a single encryption subkey] - Options for each subkey e.g. `[{sign: true, passphrase: '123'}]` diff --git a/src/packet/public_key.js b/src/packet/public_key.js index 09e2fe45..dec8d035 100644 --- a/src/packet/public_key.js +++ b/src/packet/public_key.js @@ -283,8 +283,11 @@ class PublicKeyPacket { result.bits = util.uint8ArrayBitLength(modulo); } else if (this.publicParams.oid) { result.curve = this.publicParams.oid.getName(); - } else if (this.publicParams.cipher) { - result.symmetric = this.publicParams.cipher.getName(); + } else if (this.publicParams.symAlgo) { + result.symmetric = this.publicParams.symAlgo.getName(); + result.aeadMode = this.publicParams.aeadMode.getName(); + } else if (this.publicParams.hashAlgo) { + result.symmetric = this.publicParams.hashAlgo.getName(); } return result; } diff --git a/src/packet/secret_key.js b/src/packet/secret_key.js index e94e00a6..fc06ab24 100644 --- a/src/packet/secret_key.js +++ b/src/packet/secret_key.js @@ -523,7 +523,7 @@ class SecretKeyPacket extends PublicKeyPacket { } } - async generate(bits, curve, symmetric) { + async generate(bits, curve, symmetric, aeadMode) { // The deprecated OIDs for Ed25519Legacy and Curve25519Legacy are used in legacy version 4 keys and signatures. // Implementations MUST NOT accept or generate v6 key material using the deprecated OIDs. if (this.version === 6 && ( @@ -538,7 +538,7 @@ class SecretKeyPacket extends PublicKeyPacket { )) { throw new Error(`Cannot generate v${this.version} keys of type 'pqc'. Generate a v6 key instead`); } - const { privateParams, publicParams } = await crypto.generateParams(this.algorithm, bits, curve, symmetric); + const { privateParams, publicParams } = await crypto.generateParams(this.algorithm, bits, curve, symmetric, aeadMode); this.privateParams = privateParams; this.publicParams = publicParams; this.isEncrypted = false; diff --git a/src/type/short_byte_string.js b/src/type/short_byte_string.js deleted file mode 100644 index 1611e16f..00000000 --- a/src/type/short_byte_string.js +++ /dev/null @@ -1,32 +0,0 @@ -import util from '../util'; - -class ShortByteString { - constructor(data) { - if (typeof data === 'undefined') { - data = new Uint8Array([]); - } - if (!util.isUint8Array(data)) { - throw new Error('data must be in the form of a Uint8Array'); - } - this.data = data; - this.length = this.data.byteLength; - } - - write() { - return util.concatUint8Array([new Uint8Array([this.length]), this.data]); - } - - read(input) { - if (input.length >= 1) { - const length = input[0]; - if (input.length >= length + 1) { - this.data = input.subarray(1, 1 + length); - this.length = length; - return 1 + length; - } - } - throw new Error('Invalid octet string'); - } -} - -export default ShortByteString; diff --git a/test/general/key.js b/test/general/key.js index ace5298d..2c064371 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -4757,7 +4757,7 @@ I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUrk0mXubZvyl4GBg== expect(subKey).to.exist; expect(newPrivateKey.getSubkeys().length).to.be.equal(total + 1); expect(subKey.getAlgorithmInfo().symmetric).to.be.equal('aes256'); - expect(subKey.keyPacket.publicParams.digest).to.exist.and.to.have.length(32); + expect(subKey.keyPacket.publicParams.fpSeed).to.exist.and.to.have.length(32); expect(subKey.keyPacket.privateParams.keyMaterial).to.exist.and.to.have.length(32); await subKey.verify(privateKey.primaryKey); }); @@ -4773,9 +4773,9 @@ I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUrk0mXubZvyl4GBg== expect(newKey.getSubkeys().length).to.be.equal(1); expect(subKey).to.exist; expect(subKey.getAlgorithmInfo().symmetric).to.be.equal('aes256'); - expect(subKey.keyPacket.publicParams.cipher).to.exist; - expect(subKey.keyPacket.publicParams.cipher.getValue()).to.be.equal(openpgp.enums.symmetric.aes256); - expect(subKey.keyPacket.publicParams.digest).to.exist.and.to.have.length(32); + expect(subKey.keyPacket.publicParams.symAlgo).to.exist; + expect(subKey.keyPacket.publicParams.symAlgo.getValue()).to.be.equal(openpgp.enums.symmetric.aes256); + expect(subKey.keyPacket.publicParams.fpSeed).to.exist.and.to.have.length(32); expect(subKey.keyPacket.privateParams.keyMaterial).to.exist.and.to.have.length(32); await subKey.verify(newKey.primaryKey); }); @@ -4789,9 +4789,9 @@ I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUrk0mXubZvyl4GBg== expect(privateKey.getSubkeys().length).to.be.equal(1); expect(subKey).to.exist; expect(subKey.getAlgorithmInfo().symmetric).to.be.equal('aes256'); - expect(subKey.keyPacket.publicParams.cipher).to.exist; - expect(subKey.keyPacket.publicParams.cipher.getValue()).to.be.equal(openpgp.enums.symmetric.aes256); - expect(subKey.keyPacket.publicParams.digest).to.exist.and.to.have.length(32); + expect(subKey.keyPacket.publicParams.symAlgo).to.exist; + expect(subKey.keyPacket.publicParams.symAlgo.getValue()).to.be.equal(openpgp.enums.symmetric.aes256); + expect(subKey.keyPacket.publicParams.fpSeed).to.exist.and.to.have.length(32); expect(subKey.keyPacket.privateParams.keyMaterial).to.exist.and.to.have.length(32); await subKey.verify(privateKey.primaryKey); }); diff --git a/test/general/packet.js b/test/general/packet.js index a85ab8a1..40291b40 100644 --- a/test/general/packet.js +++ b/test/general/packet.js @@ -1229,19 +1229,17 @@ V+HOQJQxXJkVRYa3QrFUehiMzTeqqMdgC6ZqJy7+ it('Parse persistent key encrypted session key packet (PKESK encrypted with persistent symmetric key)', () => { const serializedPacket = new Uint8Array([ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x64, 0x01, 0x4c, 0x80, 0x3d, 0x9b, 0xb6, + 0x00, 0x80, 0x4c, 0x80, 0x3d, 0x9b, 0xb6, 0x44, 0x13, 0x25, 0x90, 0x24, 0x6e, 0x59, 0x0d, - 0x68, 0xee, 0x1e, 0x23, 0x75, 0x8a, 0x90, 0x85, + 0x68, 0xee, 0x1e, 0x75, 0x8a, 0x90, 0x85, 0x78, 0x1b, 0xf7, 0xc4, 0x4d, 0x58, 0xc7, 0x64, 0xd2, 0xe5, 0xb3, 0x4f, 0xf6, 0x6e, 0xef, 0x53, 0xc4, 0xc3, 0x76, 0x7b, 0xba, 0xf9, 0x03, 0x86, 0xee, 0xc0, 0x9d, 0x60, 0x23, 0xa6, 0x8a ]); - const expectedIV = new Uint8Array([ + const expectedIVAndCiphertext = new Uint8Array([ 0x4c, 0x80, 0x3d, 0x9b, 0xb6, 0x44, 0x13, 0x25, - 0x90, 0x24, 0x6e, 0x59, 0x0d, 0x68, 0xee, 0x1e - ]); - const expectedCiphertext = new Uint8Array([ + 0x90, 0x24, 0x6e, 0x59, 0x0d, 0x68, 0xee, 0x1e, 0x75, 0x8a, 0x90, 0x85, 0x78, 0x1b, 0xf7, 0xc4, 0x4d, 0x58, 0xc7, 0x64, 0xd2, 0xe5, 0xb3, 0x4f, 0xf6, 0x6e, 0xef, 0x53, 0xc4, 0xc3, 0x76, 0x7b, @@ -1252,17 +1250,15 @@ V+HOQJQxXJkVRYa3QrFUehiMzTeqqMdgC6ZqJy7+ packet.read(serializedPacket); expect(packet.publicKeyAlgorithm).to.equal(openpgp.enums.publicKey.aead); - expect(packet.encrypted.aeadMode.data).to.equal(openpgp.enums.aead.eax); - expect(util.equalsUint8Array(packet.encrypted.iv, expectedIV)).to.be.true; - expect(util.equalsUint8Array(packet.encrypted.c.data, expectedCiphertext)).to.be.true; + expect(util.equalsUint8Array(packet.encrypted.ivAndCiphertext, expectedIVAndCiphertext)).to.be.true; }); it('Parse signature packet from persistent symmetric key', () => { const serializedPacket = new Uint8Array([ - 0x04, 0x00, 0x65, 0x08, 0x00, 0x10, 0x05, 0x02, + 0x04, 0x00, 0x81, 0x08, 0x00, 0x10, 0x05, 0x02, 0x60, 0x64, 0x52, 0x28, 0x09, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x6b, 0x1d, 0x40, 0x76, 0xf9, 0x35, 0xf8, + 0x6b, 0x1d, 0x76, 0xf9, 0x35, 0xf8, 0xe4, 0xc5, 0x2f, 0x49, 0xce, 0xf7, 0x91, 0x23, 0xb4, 0x00, 0x3b, 0x77, 0x92, 0x60, 0x2a, 0xfe, 0x2e, 0x4c, 0xf5, 0x5f, 0x6c, 0x75, 0x80, 0x5a, @@ -1287,7 +1283,7 @@ V+HOQJQxXJkVRYa3QrFUehiMzTeqqMdgC6ZqJy7+ const packet = new openpgp.SignaturePacket(); packet.read(serializedPacket); - const readMAC = packet.params.mac.data; + const readMAC = packet.params.mac; expect(packet.publicKeyAlgorithm).to.equal(openpgp.enums.publicKey.hmac); expect(util.equalsUint8Array(readMAC, expectedMAC)).to.be.true; @@ -1297,7 +1293,7 @@ V+HOQJQxXJkVRYa3QrFUehiMzTeqqMdgC6ZqJy7+ const persistentSymmetricKeyPacket = new openpgp.SecretSubkeyPacket(); persistentSymmetricKeyPacket.version = 4; persistentSymmetricKeyPacket.algorithm = openpgp.enums.publicKey.aead; - await persistentSymmetricKeyPacket.generate(null, null, openpgp.enums.symmetric.aes256); + await persistentSymmetricKeyPacket.generate(null, null, openpgp.enums.symmetric.aes256, openpgp.enums.aead.gcm); await persistentSymmetricKeyPacket.computeFingerprintAndKeyID(); const sessionKey = new Uint8Array([1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2]);