Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/openpgpjs/openpgpjs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlarabr <larabr@protonmail.com>2021-11-22 13:51:27 +0300
committerGitHub <noreply@github.com>2021-11-22 13:51:27 +0300
commit6da1c53de7852000fd63bacf1809b7e1ea17cf11 (patch)
treee657cd272ac4afcb6fe9ef12d2aeaed02c9e7e8c
parent03fa68dbb6c60f9a0bd319900eca442bad51c722 (diff)
Replace strings with integer algorithm identifiers in packet classes (#1410)
In several packet classes, we used to store string identifiers for public-key, aead, cipher or hash algorithms. To make the code consistent and to avoid having to convert to/from string values, we now always store integer values instead, e.g. `enums.symmetric.aes128` is used instead of `'aes128'`. This is not expected to be a breaking change for most library users. Note that the type of `Key.getAlgorithmInfo()` and of the session key objects returned and accepted by top-level functions remain unchanged. Affected classes (type changes for some properties and method's arguments): - `PublicKeyPacket`, `PublicSubkeyPacket`, `SecretKeyPacket`, `SecretSubkeyPacket` - `SymEncryptedIntegrityProtectedDataPacket`, `AEADEncryptedDataPacket`, `SymmetricallyEncryptedDataPacket` - `LiteralDataPacket`, `CompressedDataPacket` - `PublicKeyEncryptedSessionKey`, `SymEncryptedSessionKeyPacket` - `SignaturePacket` Other potentially breaking changes: - Removed property `AEADEncryptedDataPacket.aeadAlgo`, since it was redudant given `.aeadAlgorithm`. - Renamed `AEADEncryptedDataPacket.cipherAlgo` -> `.cipherAlgorithm`
-rw-r--r--openpgp.d.ts25
-rw-r--r--src/crypto/cipher/aes.js5
-rw-r--r--src/crypto/crypto.js29
-rw-r--r--src/crypto/hash/index.js36
-rw-r--r--src/crypto/mode/cfb.js40
-rw-r--r--src/crypto/mode/eax.js7
-rw-r--r--src/crypto/mode/gcm.js7
-rw-r--r--src/crypto/mode/ocb.js7
-rw-r--r--src/crypto/public_key/elliptic/curves.js5
-rw-r--r--src/crypto/public_key/elliptic/ecdh.js10
-rw-r--r--src/enums.js17
-rw-r--r--src/key/helper.js24
-rw-r--r--src/message.js48
-rw-r--r--src/packet/aead_encrypted_data.js38
-rw-r--r--src/packet/compressed_data.js25
-rw-r--r--src/packet/literal_data.js12
-rw-r--r--src/packet/one_pass_signature.js8
-rw-r--r--src/packet/public_key.js14
-rw-r--r--src/packet/public_key_encrypted_session_key.js24
-rw-r--r--src/packet/secret_key.js63
-rw-r--r--src/packet/signature.js32
-rw-r--r--src/packet/sym_encrypted_integrity_protected_data.js15
-rw-r--r--src/packet/sym_encrypted_session_key.js62
-rw-r--r--src/packet/symmetrically_encrypted_data.js14
-rw-r--r--src/type/s2k.js25
-rw-r--r--test/crypto/crypto.js19
-rw-r--r--test/crypto/eax.js4
-rw-r--r--test/crypto/gcm.js11
-rw-r--r--test/crypto/ocb.js7
-rw-r--r--test/crypto/rsa.js4
-rw-r--r--test/general/config.js2
-rw-r--r--test/general/openpgp.js14
-rw-r--r--test/general/packet.js66
-rw-r--r--test/typescript/definitions.ts2
34 files changed, 407 insertions, 314 deletions
diff --git a/openpgp.d.ts b/openpgp.d.ts
index f8da6e7c..ad749754 100644
--- a/openpgp.d.ts
+++ b/openpgp.d.ts
@@ -185,8 +185,8 @@ export function decryptSessionKeys<T extends MaybeStream<Data>>(options: { messa
export function readMessage<T extends MaybeStream<string>>(options: { armoredMessage: T, config?: PartialConfig }): Promise<Message<T>>;
export function readMessage<T extends MaybeStream<Uint8Array>>(options: { binaryMessage: T, config?: PartialConfig }): Promise<Message<T>>;
-export function createMessage<T extends MaybeStream<string>>(options: { text: T, filename?: string, date?: Date, type?: DataPacketType }): Promise<Message<T>>;
-export function createMessage<T extends MaybeStream<Uint8Array>>(options: { binary: T, filename?: string, date?: Date, type?: DataPacketType }): Promise<Message<T>>;
+export function createMessage<T extends MaybeStream<string>>(options: { text: T, filename?: string, date?: Date, format?: enums.literalFormatNames }): Promise<Message<T>>;
+export function createMessage<T extends MaybeStream<Uint8Array>>(options: { binary: T, filename?: string, date?: Date, format?: enums.literalFormatNames }): Promise<Message<T>>;
export function encrypt<T extends MaybeStream<Data>>(options: EncryptOptions & { message: Message<T>, format?: 'armored' }): Promise<
T extends WebStream<infer X> ? WebStream<string> :
@@ -359,7 +359,7 @@ declare abstract class BasePacket {
* - A Subkey Packet cannot always be used when a Primary Key Packet is expected (and vice versa).
*/
declare abstract class BasePublicKeyPacket extends BasePacket {
- public algorithm: enums.publicKeyNames;
+ public algorithm: enums.publicKey;
public created: Date;
public version: number;
public getAlgorithmInfo(): AlgorithmInfo;
@@ -417,8 +417,8 @@ export class SymEncryptedIntegrityProtectedDataPacket extends BasePacket {
export class AEADEncryptedDataPacket extends BasePacket {
static readonly tag: enums.packet.aeadEncryptedData;
- private decrypt(sessionKeyAlgorithm: string, sessionKey: Uint8Array, config?: Config): void;
- private encrypt(sessionKeyAlgorithm: string, sessionKey: Uint8Array, config?: Config): void;
+ private decrypt(sessionKeyAlgorithm: enums.symmetric, sessionKey: Uint8Array, config?: Config): void;
+ private encrypt(sessionKeyAlgorithm: enums.symmetric, sessionKey: Uint8Array, config?: Config): void;
private crypt(fn: Function, sessionKey: Uint8Array, data: MaybeStream<Uint8Array>): MaybeStream<Uint8Array>
}
@@ -438,8 +438,8 @@ export class LiteralDataPacket extends BasePacket {
static readonly tag: enums.packet.literalData;
private getText(clone?: boolean): MaybeStream<string>;
private getBytes(clone?: boolean): MaybeStream<Uint8Array>;
- private setText(text: MaybeStream<string>, format?: DataPacketType);
- private setBytes(bytes: MaybeStream<Uint8Array>, format?: DataPacketType);
+ private setText(text: MaybeStream<string>, format?: enums.literal);
+ private setBytes(bytes: MaybeStream<Uint8Array>, format: enums.literal);
private setFilename(filename: string);
private getFilename(): string;
private writeHeader(): Uint8Array;
@@ -534,8 +534,6 @@ export type AnyPacket = BasePacket;
export type AnySecretKeyPacket = SecretKeyPacket | SecretSubkeyPacket;
export type AnyKeyPacket = BasePublicKeyPacket;
-type DataPacketType = 'utf8' | 'binary' | 'text' | 'mime';
-
type AllowedPackets = Map<enums.packet, object>; // mapping to Packet classes (i.e. typeof LiteralDataPacket etc.)
export class PacketList<T extends AnyPacket> extends Array<T> {
static fromBinary(bytes: MaybeStream<Uint8Array>, allowedPackets: AllowedPackets, config?: Config): PacketList<AnyPacket>; // the packet types depend on`allowedPackets`
@@ -630,7 +628,6 @@ interface SignOptions {
message: CleartextMessage | Message<MaybeStream<Data>>;
signingKeys?: MaybeArray<PrivateKey>;
format?: 'armored' | 'binary' | 'object';
- dataType?: DataPacketType;
detached?: boolean;
signingKeyIDs?: MaybeArray<KeyID>;
date?: Date;
@@ -876,4 +873,12 @@ export namespace enums {
ocb = 2,
experimentalGCM = 100 // Private algorithm
}
+
+ export type literalFormatNames = 'utf8' | 'binary' | 'text' | 'mime'
+ enum literal {
+ binary = 98,
+ text = 116,
+ utf8 = 117,
+ mime = 109
+ }
}
diff --git a/src/crypto/cipher/aes.js b/src/crypto/cipher/aes.js
index ea61cc71..8a985079 100644
--- a/src/crypto/cipher/aes.js
+++ b/src/crypto/cipher/aes.js
@@ -1,6 +1,9 @@
import { AES_ECB } from '@openpgp/asmcrypto.js/dist_es8/aes/ecb';
-// TODO use webCrypto or nodeCrypto when possible.
+/**
+ * Javascript AES implementation.
+ * This is used as fallback if the native Crypto APIs are not available.
+ */
function aes(length) {
const C = function(key) {
const aesECB = new AES_ECB(key);
diff --git a/src/crypto/crypto.js b/src/crypto/crypto.js
index 27bbdd20..ed950d43 100644
--- a/src/crypto/crypto.js
+++ b/src/crypto/crypto.js
@@ -26,6 +26,7 @@
import publicKey from './public_key';
import * as cipher from './cipher';
+import mode from './mode';
import { getRandomBytes } from './random';
import ECDHSymkey from '../type/ecdh_symkey';
import KDFParams from '../type/kdf_params';
@@ -348,7 +349,8 @@ export async function validateParams(algo, publicParams, privateParams) {
* @async
*/
export async function getPrefixRandom(algo) {
- const prefixrandom = await getRandomBytes(cipher[algo].blockSize);
+ const { blockSize } = getCipher(algo);
+ const prefixrandom = await getRandomBytes(blockSize);
const repeat = new Uint8Array([prefixrandom[prefixrandom.length - 2], prefixrandom[prefixrandom.length - 1]]);
return util.concat([prefixrandom, repeat]);
}
@@ -361,5 +363,28 @@ export async function getPrefixRandom(algo) {
* @async
*/
export function generateSessionKey(algo) {
- return getRandomBytes(cipher[algo].keySize);
+ const { keySize } = getCipher(algo);
+ return getRandomBytes(keySize);
+}
+
+/**
+ * Get implementation of the given AEAD mode
+ * @param {enums.aead} algo
+ * @returns {Object}
+ * @throws {Error} on invalid algo
+ */
+export function getAEADMode(algo) {
+ const algoName = enums.read(enums.aead, algo);
+ return mode[algoName];
+}
+
+/**
+ * Get implementation of the given cipher
+ * @param {enums.symmetric} algo
+ * @returns {Object}
+ * @throws {Error} on invalid algo
+ */
+export function getCipher(algo) {
+ const algoName = enums.read(enums.symmetric, algo);
+ return cipher[algoName];
}
diff --git a/src/crypto/hash/index.js b/src/crypto/hash/index.js
index 76deb9c6..cfec8d38 100644
--- a/src/crypto/hash/index.js
+++ b/src/crypto/hash/index.js
@@ -16,6 +16,7 @@ import * as stream from '@openpgp/web-stream-tools';
import md5 from './md5';
import util from '../../util';
import defaultConfig from '../../config';
+import enums from '../../enums';
const webCrypto = util.getWebCrypto();
const nodeCrypto = util.getNodeCrypto();
@@ -110,26 +111,19 @@ export default {
*/
digest: function(algo, data) {
switch (algo) {
- case 1:
- // - MD5 [HAC]
+ case enums.hash.md5:
return this.md5(data);
- case 2:
- // - SHA-1 [FIPS180]
+ case enums.hash.sha1:
return this.sha1(data);
- case 3:
- // - RIPE-MD/160 [HAC]
+ case enums.hash.ripemd:
return this.ripemd(data);
- case 8:
- // - SHA256 [FIPS180]
+ case enums.hash.sha256:
return this.sha256(data);
- case 9:
- // - SHA384 [FIPS180]
+ case enums.hash.sha384:
return this.sha384(data);
- case 10:
- // - SHA512 [FIPS180]
+ case enums.hash.sha512:
return this.sha512(data);
- case 11:
- // - SHA224 [FIPS180]
+ case enums.hash.sha224:
return this.sha224(data);
default:
throw new Error('Invalid hash function.');
@@ -143,18 +137,18 @@ export default {
*/
getHashByteLength: function(algo) {
switch (algo) {
- case 1: // - MD5 [HAC]
+ case enums.hash.md5:
return 16;
- case 2: // - SHA-1 [FIPS180]
- case 3: // - RIPE-MD/160 [HAC]
+ case enums.hash.sha1:
+ case enums.hash.ripemd:
return 20;
- case 8: // - SHA256 [FIPS180]
+ case enums.hash.sha256:
return 32;
- case 9: // - SHA384 [FIPS180]
+ case enums.hash.sha384:
return 48;
- case 10: // - SHA512 [FIPS180]
+ case enums.hash.sha512:
return 64;
- case 11: // - SHA224 [FIPS180]
+ case enums.hash.sha224:
return 28;
default:
throw new Error('Invalid hash algorithm.');
diff --git a/src/crypto/mode/cfb.js b/src/crypto/mode/cfb.js
index c1162e99..1871bcda 100644
--- a/src/crypto/mode/cfb.js
+++ b/src/crypto/mode/cfb.js
@@ -27,6 +27,7 @@ import { AES_CFB } from '@openpgp/asmcrypto.js/dist_es8/aes/cfb';
import * as stream from '@openpgp/web-stream-tools';
import * as cipher from '../cipher';
import util from '../../util';
+import enums from '../../enums';
const webCrypto = util.getWebCrypto();
const nodeCrypto = util.getNodeCrypto();
@@ -43,15 +44,25 @@ const nodeAlgos = {
/* twofish is not implemented in OpenSSL */
};
+/**
+ * CFB encryption
+ * @param {enums.symmetric} algo - block cipher algorithm
+ * @param {Uint8Array} key
+ * @param {MaybeStream<Uint8Array>} plaintext
+ * @param {Uint8Array} iv
+ * @param {Object} config - full configuration, defaults to openpgp.config
+ * @returns MaybeStream<Uint8Array>
+ */
export async function encrypt(algo, key, plaintext, iv, config) {
- if (util.getNodeCrypto() && nodeAlgos[algo]) { // Node crypto library.
+ const algoName = enums.read(enums.symmetric, algo);
+ if (util.getNodeCrypto() && nodeAlgos[algoName]) { // Node crypto library.
return nodeEncrypt(algo, key, plaintext, iv);
}
- if (algo.substr(0, 3) === 'aes') {
+ if (algoName.substr(0, 3) === 'aes') {
return aesEncrypt(algo, key, plaintext, iv, config);
}
- const cipherfn = new cipher[algo](key);
+ const cipherfn = new cipher[algoName](key);
const block_size = cipherfn.blockSize;
const blockc = iv.slice();
@@ -76,15 +87,24 @@ export async function encrypt(algo, key, plaintext, iv, config) {
return stream.transform(plaintext, process, process);
}
+/**
+ * CFB decryption
+ * @param {enums.symmetric} algo - block cipher algorithm
+ * @param {Uint8Array} key
+ * @param {MaybeStream<Uint8Array>} ciphertext
+ * @param {Uint8Array} iv
+ * @returns MaybeStream<Uint8Array>
+ */
export async function decrypt(algo, key, ciphertext, iv) {
- if (util.getNodeCrypto() && nodeAlgos[algo]) { // Node crypto library.
+ const algoName = enums.read(enums.symmetric, algo);
+ if (util.getNodeCrypto() && nodeAlgos[algoName]) { // Node crypto library.
return nodeDecrypt(algo, key, ciphertext, iv);
}
- if (algo.substr(0, 3) === 'aes') {
+ if (algoName.substr(0, 3) === 'aes') {
return aesDecrypt(algo, key, ciphertext, iv);
}
- const cipherfn = new cipher[algo](key);
+ const cipherfn = new cipher[algoName](key);
const block_size = cipherfn.blockSize;
let blockp = iv;
@@ -140,7 +160,7 @@ function xorMut(a, b) {
async function webEncrypt(algo, key, pt, iv) {
const ALGO = 'AES-CBC';
const _key = await webCrypto.importKey('raw', key, { name: ALGO }, false, ['encrypt']);
- const { blockSize } = cipher[algo];
+ const { blockSize } = crypto.getCipher(algo);
const cbc_pt = util.concatUint8Array([new Uint8Array(blockSize), pt]);
const ct = new Uint8Array(await webCrypto.encrypt({ name: ALGO, iv }, _key, cbc_pt)).subarray(0, pt.length);
xorMut(ct, pt);
@@ -148,11 +168,13 @@ async function webEncrypt(algo, key, pt, iv) {
}
function nodeEncrypt(algo, key, pt, iv) {
- const cipherObj = new nodeCrypto.createCipheriv(nodeAlgos[algo], key, iv);
+ const algoName = enums.read(enums.symmetric, algo);
+ const cipherObj = new nodeCrypto.createCipheriv(nodeAlgos[algoName], key, iv);
return stream.transform(pt, value => new Uint8Array(cipherObj.update(value)));
}
function nodeDecrypt(algo, key, ct, iv) {
- const decipherObj = new nodeCrypto.createDecipheriv(nodeAlgos[algo], key, iv);
+ const algoName = enums.read(enums.symmetric, algo);
+ const decipherObj = new nodeCrypto.createDecipheriv(nodeAlgos[algoName], key, iv);
return stream.transform(ct, value => new Uint8Array(decipherObj.update(value)));
}
diff --git a/src/crypto/mode/eax.js b/src/crypto/mode/eax.js
index 6d3e434c..cf68c460 100644
--- a/src/crypto/mode/eax.js
+++ b/src/crypto/mode/eax.js
@@ -25,6 +25,7 @@
import { AES_CTR } from '@openpgp/asmcrypto.js/dist_es8/aes/ctr';
import CMAC from '../cmac';
import util from '../../util';
+import enums from '../../enums';
const webCrypto = util.getWebCrypto();
const nodeCrypto = util.getNodeCrypto();
@@ -74,11 +75,13 @@ async function CTR(key) {
/**
* Class to en/decrypt using EAX mode.
- * @param {String} cipher - The symmetric cipher algorithm to use e.g. 'aes128'
+ * @param {enums.symmetric} cipher - The symmetric cipher algorithm to use
* @param {Uint8Array} key - The encryption key
*/
async function EAX(cipher, key) {
- if (cipher.substr(0, 3) !== 'aes') {
+ if (cipher !== enums.symmetric.aes128 &&
+ cipher !== enums.symmetric.aes192 &&
+ cipher !== enums.symmetric.aes256) {
throw new Error('EAX mode supports only AES cipher');
}
diff --git a/src/crypto/mode/gcm.js b/src/crypto/mode/gcm.js
index 4532eb96..424b7e1a 100644
--- a/src/crypto/mode/gcm.js
+++ b/src/crypto/mode/gcm.js
@@ -24,6 +24,7 @@
import { AES_GCM } from '@openpgp/asmcrypto.js/dist_es8/aes/gcm';
import util from '../../util';
+import enums from '../../enums';
const webCrypto = util.getWebCrypto();
const nodeCrypto = util.getNodeCrypto();
@@ -36,11 +37,13 @@ const ALGO = 'AES-GCM';
/**
* Class to en/decrypt using GCM mode.
- * @param {String} cipher - The symmetric cipher algorithm to use e.g. 'aes128'
+ * @param {enums.symmetric} cipher - The symmetric cipher algorithm to use
* @param {Uint8Array} key - The encryption key
*/
async function GCM(cipher, key) {
- if (cipher.substr(0, 3) !== 'aes') {
+ if (cipher !== enums.symmetric.aes128 &&
+ cipher !== enums.symmetric.aes192 &&
+ cipher !== enums.symmetric.aes256) {
throw new Error('GCM mode supports only AES cipher');
}
diff --git a/src/crypto/mode/ocb.js b/src/crypto/mode/ocb.js
index 9a6e60fe..868b0ebc 100644
--- a/src/crypto/mode/ocb.js
+++ b/src/crypto/mode/ocb.js
@@ -23,7 +23,7 @@
import * as ciphers from '../cipher';
import util from '../../util';
-
+import enums from '../../enums';
const blockLength = 16;
const ivLength = 15;
@@ -59,7 +59,7 @@ const one = new Uint8Array([1]);
/**
* Class to en/decrypt using OCB mode.
- * @param {String} cipher - The symmetric cipher algorithm to use e.g. 'aes128'
+ * @param {enums.symmetric} cipher - The symmetric cipher algorithm to use
* @param {Uint8Array} key - The encryption key
*/
async function OCB(cipher, key) {
@@ -72,7 +72,8 @@ async function OCB(cipher, key) {
constructKeyVariables(cipher, key);
function constructKeyVariables(cipher, key) {
- const aes = new ciphers[cipher](key);
+ const cipherName = enums.read(enums.symmetric, cipher);
+ const aes = new ciphers[cipherName](key);
encipher = aes.encrypt.bind(aes);
decipher = aes.decrypt.bind(aes);
diff --git a/src/crypto/public_key/elliptic/curves.js b/src/crypto/public_key/elliptic/curves.js
index 02db72b5..e3a0f686 100644
--- a/src/crypto/public_key/elliptic/curves.js
+++ b/src/crypto/public_key/elliptic/curves.js
@@ -220,6 +220,11 @@ async function generate(curve) {
};
}
+/**
+ * Get preferred hash algo to use with the given curve
+ * @param {module:type/oid} oid - curve oid
+ * @returns {enums.hash} hash algorithm
+ */
function getPreferredHashAlgo(oid) {
return curves[enums.write(enums.curve, oid.toHex())].hash;
}
diff --git a/src/crypto/public_key/elliptic/ecdh.js b/src/crypto/public_key/elliptic/ecdh.js
index d09f52df..a5de7187 100644
--- a/src/crypto/public_key/elliptic/ecdh.js
+++ b/src/crypto/public_key/elliptic/ecdh.js
@@ -24,7 +24,6 @@
import nacl from '@openpgp/tweetnacl/nacl-fast-light.js';
import { Curve, jwkToRawPublic, rawPublicToJWK, privateToJWK, validateStandardParams } from './curves';
import * as aesKW from '../../aes_kw';
-import * as cipher from '../../cipher';
import { getRandomBytes } from '../../random';
import hash from '../../hash';
import enums from '../../../enums';
@@ -32,6 +31,7 @@ import util from '../../../util';
import { b64ToUint8Array } from '../../../encoding/base64';
import * as pkcs5 from '../../pkcs5';
import { keyFromPublic, keyFromPrivate, getIndutnyCurve } from './indutnyKey';
+import { getCipher } from '../../crypto';
const webCrypto = util.getWebCrypto();
const nodeCrypto = util.getNodeCrypto();
@@ -132,8 +132,8 @@ export async function encrypt(oid, kdfParams, data, Q, fingerprint) {
const curve = new Curve(oid);
const { publicKey, sharedKey } = await genPublicEphemeralKey(curve, Q);
const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint);
- const cipherAlgo = enums.read(enums.symmetric, kdfParams.cipher);
- const Z = await kdf(kdfParams.hash, sharedKey, cipher[cipherAlgo].keySize, param);
+ const { keySize } = getCipher(kdfParams.cipher);
+ const Z = await kdf(kdfParams.hash, sharedKey, keySize, param);
const wrappedKey = aesKW.wrap(Z, m);
return { publicKey, wrappedKey };
}
@@ -192,12 +192,12 @@ export async function decrypt(oid, kdfParams, V, C, Q, d, fingerprint) {
const curve = new Curve(oid);
const { sharedKey } = await genPrivateEphemeralKey(curve, V, Q, d);
const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint);
- const cipherAlgo = enums.read(enums.symmetric, kdfParams.cipher);
+ const { keySize } = getCipher(kdfParams.cipher);
let err;
for (let i = 0; i < 3; i++) {
try {
// Work around old go crypto bug and old OpenPGP.js bug, respectively.
- const Z = await kdf(kdfParams.hash, sharedKey, cipher[cipherAlgo].keySize, param, i === 1, i === 2);
+ const Z = await kdf(kdfParams.hash, sharedKey, keySize, param, i === 1, i === 2);
return pkcs5.decode(aesKW.unwrap(Z, C));
} catch (e) {
err = e;
diff --git a/src/enums.js b/src/enums.js
index 16c31601..3f2e15ab 100644
--- a/src/enums.js
+++ b/src/enums.js
@@ -448,7 +448,13 @@ export default {
v5Keys: 4
},
- /** Asserts validity and converts from string/integer to integer. */
+ /**
+ * Asserts validity of given value and converts from string/integer to integer.
+ * @param {Object} type target enum type
+ * @param {String|Integer} e value to check and/or convert
+ * @returns {Integer} enum value if it exists
+ * @throws {Error} if the value is invalid
+ */
write: function(type, e) {
if (typeof e === 'number') {
e = this.read(type, e);
@@ -461,7 +467,13 @@ export default {
throw new Error('Invalid enum value.');
},
- /** Converts from an integer to string. */
+ /**
+ * Converts enum integer value to the corresponding string, if it exists.
+ * @param {Object} type target enum type
+ * @param {Integer} e value to convert
+ * @returns {String} name of enum value if it exists
+ * @throws {Error} if the value is invalid
+ */
read: function(type, e) {
if (!type[byValue]) {
type[byValue] = [];
@@ -476,5 +488,4 @@ export default {
throw new Error('Invalid enum value.');
}
-
};
diff --git a/src/key/helper.js b/src/key/helper.js
index a24d3f1c..0720dde2 100644
--- a/src/key/helper.js
+++ b/src/key/helper.js
@@ -19,7 +19,7 @@ import defaultConfig from '../config';
export async function generateSecretSubkey(options, config) {
const secretSubkeyPacket = new SecretSubkeyPacket(options.date, config);
secretSubkeyPacket.packets = null;
- secretSubkeyPacket.algorithm = enums.read(enums.publicKey, options.algorithm);
+ secretSubkeyPacket.algorithm = enums.write(enums.publicKey, options.algorithm);
await secretSubkeyPacket.generate(options.rsaBits, options.curve);
await secretSubkeyPacket.computeFingerprintAndKeyID();
return secretSubkeyPacket;
@@ -28,7 +28,7 @@ export async function generateSecretSubkey(options, config) {
export async function generateSecretKey(options, config) {
const secretKeyPacket = new SecretKeyPacket(options.date, config);
secretKeyPacket.packets = null;
- secretKeyPacket.algorithm = enums.read(enums.publicKey, options.algorithm);
+ secretKeyPacket.algorithm = enums.write(enums.publicKey, options.algorithm);
await secretKeyPacket.generate(options.rsaBits, options.curve, options.config);
await secretKeyPacket.computeFingerprintAndKeyID();
return secretKeyPacket;
@@ -115,7 +115,7 @@ export async function createBindingSignature(subkey, primaryKey, options, config
* @param {Date} [date] - Use the given date for verification instead of the current time
* @param {Object} [userID] - User ID
* @param {Object} config - full configuration
- * @returns {Promise<String>}
+ * @returns {Promise<enums.hash>}
* @async
*/
export async function getPreferredHashAlgo(key, keyPacket, date = new Date(), userID = {}, config) {
@@ -135,9 +135,9 @@ export async function getPreferredHashAlgo(key, keyPacket, date = new Date(), us
case SecretSubkeyPacket.prototype:
case PublicSubkeyPacket.prototype:
switch (keyPacket.algorithm) {
- case 'ecdh':
- case 'ecdsa':
- case 'eddsa':
+ case enums.publicKey.ecdh:
+ case enums.publicKey.ecdsa:
+ case enums.publicKey.eddsa:
prefAlgo = crypto.publicKey.elliptic.getPreferredHashAlgo(keyPacket.publicParams.oid);
}
}
@@ -147,7 +147,7 @@ export async function getPreferredHashAlgo(key, keyPacket, date = new Date(), us
/**
* Returns the preferred symmetric/aead/compression algorithm for a set of keys
- * @param {symmetric|aead|compression} type - Type of preference to return
+ * @param {'symmetric'|'aead'|'compression'} type - Type of preference to return
* @param {Array<Key>} [keys] - Set of keys
* @param {Date} [date] - Use the given date for verification instead of the current time
* @param {Array} [userIDs] - User IDs
@@ -361,7 +361,7 @@ export function sanitizeKeyOptions(options, subkeyDefaults = {}) {
}
export function isValidSigningKeyPacket(keyPacket, signature) {
- const keyAlgo = enums.write(enums.publicKey, keyPacket.algorithm);
+ const keyAlgo = keyPacket.algorithm;
return keyAlgo !== enums.publicKey.rsaEncrypt &&
keyAlgo !== enums.publicKey.elgamal &&
keyAlgo !== enums.publicKey.ecdh &&
@@ -370,7 +370,7 @@ export function isValidSigningKeyPacket(keyPacket, signature) {
}
export function isValidEncryptionKeyPacket(keyPacket, signature) {
- const keyAlgo = enums.write(enums.publicKey, keyPacket.algorithm);
+ const keyAlgo = keyPacket.algorithm;
return keyAlgo !== enums.publicKey.dsa &&
keyAlgo !== enums.publicKey.rsaSign &&
keyAlgo !== enums.publicKey.ecdsa &&
@@ -400,10 +400,10 @@ export function isValidDecryptionKeyPacket(signature, config) {
*/
export function checkKeyRequirements(keyPacket, config) {
const keyAlgo = enums.write(enums.publicKey, keyPacket.algorithm);
+ const algoInfo = keyPacket.getAlgorithmInfo();
if (config.rejectPublicKeyAlgorithms.has(keyAlgo)) {
- throw new Error(`${keyPacket.algorithm} keys are considered too weak.`);
+ throw new Error(`${algoInfo.algorithm} keys are considered too weak.`);
}
- const algoInfo = keyPacket.getAlgorithmInfo();
switch (keyAlgo) {
case enums.publicKey.rsaEncryptSign:
case enums.publicKey.rsaSign:
@@ -416,7 +416,7 @@ export function checkKeyRequirements(keyPacket, config) {
case enums.publicKey.eddsa:
case enums.publicKey.ecdh:
if (config.rejectCurves.has(algoInfo.curve)) {
- throw new Error(`Support for ${keyPacket.algorithm} keys using curve ${algoInfo.curve} is disabled.`);
+ throw new Error(`Support for ${algoInfo.algorithm} keys using curve ${algoInfo.curve} is disabled.`);
}
break;
default:
diff --git a/src/message.js b/src/message.js
index 950c3f6c..d94c6e80 100644
--- a/src/message.js
+++ b/src/message.js
@@ -107,7 +107,7 @@ export class Message {
* @async
*/
async decrypt(decryptionKeys, passwords, sessionKeys, date = new Date(), config = defaultConfig) {
- const keyObjs = sessionKeys || await this.decryptSessionKeys(decryptionKeys, passwords, date, config);
+ const sessionKeyObjs = sessionKeys || await this.decryptSessionKeys(decryptionKeys, passwords, date, config);
const symEncryptedPacketlist = this.packets.filterByTag(
enums.packet.symmetricallyEncryptedData,
@@ -121,13 +121,14 @@ export class Message {
const symEncryptedPacket = symEncryptedPacketlist[0];
let exception = null;
- const decryptedPromise = Promise.all(keyObjs.map(async keyObj => {
- if (!keyObj || !util.isUint8Array(keyObj.data) || !util.isString(keyObj.algorithm)) {
+ const decryptedPromise = Promise.all(sessionKeyObjs.map(async ({ algorithm: algorithmName, data }) => {
+ if (!util.isUint8Array(data) || !util.isString(algorithmName)) {
throw new Error('Invalid session key for decryption.');
}
try {
- await symEncryptedPacket.decrypt(keyObj.algorithm, keyObj.data, config);
+ const algo = enums.write(enums.symmetric, algorithmName);
+ await symEncryptedPacket.decrypt(algo, data, config);
} catch (e) {
util.printDebugError(e);
exception = e;
@@ -216,7 +217,7 @@ export class Message {
}
try {
await keyPacket.decrypt(decryptionKeyPacket);
- if (!algos.includes(enums.write(enums.symmetric, keyPacket.sessionKeyAlgorithm))) {
+ if (!algos.includes(keyPacket.sessionKeyAlgorithm)) {
throw new Error('A non-preferred symmetric algorithm was used.');
}
keyPackets.push(keyPacket);
@@ -247,7 +248,10 @@ export class Message {
});
}
- return keyPackets.map(packet => ({ data: packet.sessionKey, algorithm: packet.sessionKeyAlgorithm }));
+ return keyPackets.map(packet => ({
+ data: packet.sessionKey,
+ algorithm: enums.read(enums.symmetric, packet.sessionKeyAlgorithm)
+ }));
}
throw exception || new Error('Session key decryption failed.');
}
@@ -295,13 +299,14 @@ export class Message {
* @async
*/
static async generateSessionKey(encryptionKeys = [], date = new Date(), userIDs = [], config = defaultConfig) {
- const algorithm = enums.read(enums.symmetric, await getPreferredAlgo('symmetric', encryptionKeys, date, userIDs, config));
- const aeadAlgorithm = config.aeadProtect && await isAEADSupported(encryptionKeys, date, userIDs, config) ?
+ const algo = await getPreferredAlgo('symmetric', encryptionKeys, date, userIDs, config);
+ const algorithmName = enums.read(enums.symmetric, algo);
+ const aeadAlgorithmName = config.aeadProtect && await isAEADSupported(encryptionKeys, date, userIDs, config) ?
enums.read(enums.aead, await getPreferredAlgo('aead', encryptionKeys, date, userIDs, config)) :
undefined;
- const sessionKeyData = await crypto.generateSessionKey(algorithm);
- return { data: sessionKeyData, algorithm, aeadAlgorithm };
+ const sessionKeyData = await crypto.generateSessionKey(algo);
+ return { data: sessionKeyData, algorithm: algorithmName, aeadAlgorithm: aeadAlgorithmName };
}
/**
@@ -330,19 +335,20 @@ export class Message {
throw new Error('No keys, passwords, or session key provided.');
}
- const { data: sessionKeyData, algorithm, aeadAlgorithm } = sessionKey;
+ const { data: sessionKeyData, algorithm: algorithmName, aeadAlgorithm: aeadAlgorithmName } = sessionKey;
- const msg = await Message.encryptSessionKey(sessionKeyData, algorithm, aeadAlgorithm, encryptionKeys, passwords, wildcard, encryptionKeyIDs, date, userIDs, config);
+ const msg = await Message.encryptSessionKey(sessionKeyData, algorithmName, aeadAlgorithmName, encryptionKeys, passwords, wildcard, encryptionKeyIDs, date, userIDs, config);
let symEncryptedPacket;
- if (aeadAlgorithm) {
+ if (aeadAlgorithmName) {
symEncryptedPacket = new AEADEncryptedDataPacket();
- symEncryptedPacket.aeadAlgorithm = aeadAlgorithm;
+ symEncryptedPacket.aeadAlgorithm = enums.write(enums.aead, aeadAlgorithmName);
} else {
symEncryptedPacket = new SymEncryptedIntegrityProtectedDataPacket();
}
symEncryptedPacket.packets = this.packets;
+ const algorithm = enums.write(enums.symmetric, algorithmName);
await symEncryptedPacket.encrypt(algorithm, sessionKeyData, config);
msg.packets.push(symEncryptedPacket);
@@ -353,8 +359,8 @@ export class Message {
/**
* Encrypt a session key either with public keys, passwords, or both at once.
* @param {Uint8Array} sessionKey - session key for encryption
- * @param {String} algorithm - session key algorithm
- * @param {String} [aeadAlgorithm] - AEAD algorithm, e.g. 'eax' or 'ocb'
+ * @param {String} algorithmName - session key algorithm
+ * @param {String} [aeadAlgorithmName] - AEAD algorithm, e.g. 'eax' or 'ocb'
* @param {Array<PublicKey>} [encryptionKeys] - Public key(s) for message encryption
* @param {Array<String>} [passwords] - For message encryption
* @param {Boolean} [wildcard] - Use a key ID of 0 instead of the public key IDs
@@ -365,8 +371,10 @@ export class Message {
* @returns {Promise<Message>} New message with encrypted content.
* @async
*/
- static async encryptSessionKey(sessionKey, algorithm, aeadAlgorithm, encryptionKeys, passwords, wildcard = false, encryptionKeyIDs = [], date = new Date(), userIDs = [], config = defaultConfig) {
+ static async encryptSessionKey(sessionKey, algorithmName, aeadAlgorithmName, encryptionKeys, passwords, wildcard = false, encryptionKeyIDs = [], date = new Date(), userIDs = [], config = defaultConfig) {
const packetlist = new PacketList();
+ const algorithm = enums.write(enums.symmetric, algorithmName);
+ const aeadAlgorithm = aeadAlgorithmName && enums.write(enums.aead, aeadAlgorithmName);
if (encryptionKeys) {
const results = await Promise.all(encryptionKeys.map(async function(primaryKey, i) {
@@ -499,7 +507,7 @@ export class Message {
}
const compressed = new CompressedDataPacket(config);
- compressed.algorithm = enums.read(enums.compression, algo);
+ compressed.algorithm = algo;
compressed.packets = this.packets;
const packetList = new PacketList();
@@ -866,9 +874,9 @@ export async function createMessage({ text, binary, filename, date = new Date(),
}
const literalDataPacket = new LiteralDataPacket(date);
if (text !== undefined) {
- literalDataPacket.setText(input, format);
+ literalDataPacket.setText(input, enums.write(enums.literal, format));
} else {
- literalDataPacket.setBytes(input, format);
+ literalDataPacket.setBytes(input, enums.write(enums.literal, format));
}
if (filename !== undefined) {
literalDataPacket.setFilename(filename);
diff --git a/src/packet/aead_encrypted_data.js b/src/packet/aead_encrypted_data.js
index d913cb85..01a305f7 100644
--- a/src/packet/aead_encrypted_data.js
+++ b/src/packet/aead_encrypted_data.js
@@ -52,9 +52,10 @@ class AEADEncryptedDataPacket {
constructor() {
this.version = VERSION;
- this.cipherAlgo = null;
- this.aeadAlgorithm = 'eax';
- this.aeadAlgo = null;
+ /** @type {enums.symmetric} */
+ this.cipherAlgorithm = null;
+ /** @type {enums.aead} */
+ this.aeadAlgorithm = enums.aead.eax;
this.chunkSizeByte = null;
this.iv = null;
this.encrypted = null;
@@ -64,6 +65,7 @@ class AEADEncryptedDataPacket {
/**
* Parse an encrypted payload of bytes in the order: version, IV, ciphertext (see specification)
* @param {Uint8Array | ReadableStream<Uint8Array>} bytes
+ * @throws {Error} on parsing failure
*/
async read(bytes) {
await stream.parse(bytes, async reader => {
@@ -71,10 +73,11 @@ class AEADEncryptedDataPacket {
if (version !== VERSION) { // The only currently defined value is 1.
throw new UnsupportedError(`Version ${version} of the AEAD-encrypted data packet is not supported.`);
}
- this.cipherAlgo = await reader.readByte();
- this.aeadAlgo = await reader.readByte();
+ this.cipherAlgorithm = await reader.readByte();
+ this.aeadAlgorithm = await reader.readByte();
this.chunkSizeByte = await reader.readByte();
- const mode = crypto.mode[enums.read(enums.aead, this.aeadAlgo)];
+
+ const mode = crypto.getAEADMode(this.aeadAlgorithm);
this.iv = await reader.readBytes(mode.ivLength);
this.encrypted = reader.remainder();
});
@@ -85,12 +88,12 @@ class AEADEncryptedDataPacket {
* @returns {Uint8Array | ReadableStream<Uint8Array>} The encrypted payload.
*/
write() {
- return util.concat([new Uint8Array([this.version, this.cipherAlgo, this.aeadAlgo, this.chunkSizeByte]), this.iv, this.encrypted]);
+ return util.concat([new Uint8Array([this.version, this.cipherAlgorithm, this.aeadAlgorithm, this.chunkSizeByte]), this.iv, this.encrypted]);
}
/**
* Decrypt the encrypted payload.
- * @param {String} sessionKeyAlgorithm - The session key's cipher algorithm e.g. 'aes128'
+ * @param {enums.symmetric} sessionKeyAlgorithm - The session key's cipher algorithm
* @param {Uint8Array} key - The session key used to encrypt the payload
* @param {Object} [config] - Full configuration, defaults to openpgp.config
* @throws {Error} if decryption was not successful
@@ -105,18 +108,18 @@ class AEADEncryptedDataPacket {
}
/**
- * Encrypt the packet list payload.
- * @param {String} sessionKeyAlgorithm - The session key's cipher algorithm e.g. 'aes128'
+ * Encrypt the packet payload.
+ * @param {enums.symmetric} sessionKeyAlgorithm - The session key's cipher algorithm
* @param {Uint8Array} key - The session key used to encrypt the payload
* @param {Object} [config] - Full configuration, defaults to openpgp.config
* @throws {Error} if encryption was not successful
* @async
*/
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.cipherAlgorithm = sessionKeyAlgorithm;
+
+ const { ivLength } = crypto.getAEADMode(this.aeadAlgorithm);
+ this.iv = await crypto.random.getRandomBytes(ivLength); // generate new random IV
this.chunkSizeByte = config.aeadChunkSizeByte;
const data = this.packets.write();
this.encrypted = await this.crypt('encrypt', key, data);
@@ -131,9 +134,8 @@ class AEADEncryptedDataPacket {
* @async
*/
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);
+ const mode = crypto.getAEADMode(this.aeadAlgorithm);
+ const modeInstance = await mode(this.cipherAlgorithm, key);
const tagLengthIfDecrypting = fn === 'decrypt' ? mode.tagLength : 0;
const tagLengthIfEncrypting = fn === 'encrypt' ? mode.tagLength : 0;
const chunkSize = 2 ** (this.chunkSizeByte + 6) + tagLengthIfDecrypting; // ((uint64_t)1 << (c + 6))
@@ -142,7 +144,7 @@ class AEADEncryptedDataPacket {
const adataTagArray = new Uint8Array(adataBuffer);
const adataView = new DataView(adataBuffer);
const chunkIndexArray = new Uint8Array(adataBuffer, 5, 8);
- adataArray.set([0xC0 | AEADEncryptedDataPacket.tag, this.version, this.cipherAlgo, this.aeadAlgo, this.chunkSizeByte], 0);
+ adataArray.set([0xC0 | AEADEncryptedDataPacket.tag, this.version, this.cipherAlgorithm, this.aeadAlgorithm, this.chunkSizeByte], 0);
let chunkIndex = 0;
let latestPromise = Promise.resolve();
let cryptedBytes = 0;
diff --git a/src/packet/compressed_data.js b/src/packet/compressed_data.js
index 59befa81..e924a46c 100644
--- a/src/packet/compressed_data.js
+++ b/src/packet/compressed_data.js
@@ -60,9 +60,9 @@ class CompressedDataPacket {
this.packets = null;
/**
* Compression algorithm
- * @type {compression}
+ * @type {enums.compression}
*/
- this.algorithm = enums.read(enums.compression, config.preferredCompressionAlgorithm);
+ this.algorithm = config.preferredCompressionAlgorithm;
/**
* Compressed packet data
@@ -85,7 +85,7 @@ class CompressedDataPacket {
await stream.parse(bytes, async reader => {
// One octet that gives the algorithm used to compress the packet.
- this.algorithm = enums.read(enums.compression, await reader.readByte());
+ this.algorithm = await reader.readByte();
// Compressed data, which makes up the remainder of the packet.
this.compressed = reader.remainder();
@@ -104,7 +104,7 @@ class CompressedDataPacket {
this.compress();
}
- return util.concat([new Uint8Array([enums.write(enums.compression, this.algorithm)]), this.compressed]);
+ return util.concat([new Uint8Array([this.algorithm]), this.compressed]);
}
@@ -114,23 +114,26 @@ class CompressedDataPacket {
* @param {Object} [config] - Full configuration, defaults to openpgp.config
*/
async decompress(config = defaultConfig) {
-
- if (!decompress_fns[this.algorithm]) {
- throw new Error(this.algorithm + ' decompression not supported');
+ const compressionName = enums.read(enums.compression, this.algorithm);
+ const decompressionFn = decompress_fns[compressionName];
+ if (!decompressionFn) {
+ throw new Error(`${compressionName} decompression not supported`);
}
- this.packets = await PacketList.fromBinary(decompress_fns[this.algorithm](this.compressed), allowedPackets, config);
+ this.packets = await PacketList.fromBinary(decompressionFn(this.compressed), allowedPackets, config);
}
/**
* Compress the packet data (member decompressedData)
*/
compress() {
- if (!compress_fns[this.algorithm]) {
- throw new Error(this.algorithm + ' compression not supported');
+ const compressionName = enums.read(enums.compression, this.algorithm);
+ const compressionFn = compress_fns[compressionName];
+ if (!compressionFn) {
+ throw new Error(`${compressionName} compression not supported`);
}
- this.compressed = compress_fns[this.algorithm](this.packets.write(), this.deflateLevel);
+ this.compressed = compressionFn(this.packets.write(), this.deflateLevel);
}
}
diff --git a/src/packet/literal_data.js b/src/packet/literal_data.js
index 5488ffbb..8740fc53 100644
--- a/src/packet/literal_data.js
+++ b/src/packet/literal_data.js
@@ -35,7 +35,7 @@ class LiteralDataPacket {
* @param {Date} date - The creation date of the literal package
*/
constructor(date = new Date()) {
- this.format = 'utf8'; // default format for literal data packets
+ this.format = enums.literal.utf8; // default format for literal data packets
this.date = util.normalizeDate(date);
this.text = null; // textual data representation
this.data = null; // literal data representation
@@ -46,9 +46,9 @@ class LiteralDataPacket {
* Set the packet data to a javascript native string, end of line
* will be normalized to \r\n and by default text is converted to UTF8
* @param {String | ReadableStream<String>} text - Any native javascript string
- * @param {utf8|binary|text|mime} [format] - The format of the string of bytes
+ * @param {enums.literal} [format] - The format of the string of bytes
*/
- setText(text, format = 'utf8') {
+ setText(text, format = enums.literal.utf8) {
this.format = format;
this.text = text;
this.data = null;
@@ -70,7 +70,7 @@ class LiteralDataPacket {
/**
* Set the packet data to value represented by the provided string of bytes.
* @param {Uint8Array | ReadableStream<Uint8Array>} bytes - The string of bytes
- * @param {utf8|binary|text|mime} format - The format of the string of bytes
+ * @param {enums.literal} format - The format of the string of bytes
*/
setBytes(bytes, format) {
this.format = format;
@@ -123,7 +123,7 @@ class LiteralDataPacket {
async read(bytes) {
await stream.parse(bytes, async reader => {
// - A one-octet field that describes how the data is formatted.
- const format = enums.read(enums.literal, await reader.readByte());
+ const format = await reader.readByte(); // enums.literal
const filename_len = await reader.readByte();
this.filename = util.decodeUTF8(await reader.readBytes(filename_len));
@@ -145,7 +145,7 @@ class LiteralDataPacket {
const filename = util.encodeUTF8(this.filename);
const filename_length = new Uint8Array([filename.length]);
- const format = new Uint8Array([enums.write(enums.literal, this.format)]);
+ const format = new Uint8Array([this.format]);
const date = util.writeDate(this.date);
return util.concatUint8Array([format, filename_length, filename, date]);
diff --git a/src/packet/one_pass_signature.js b/src/packet/one_pass_signature.js
index 6ca206b7..54e8697d 100644
--- a/src/packet/one_pass_signature.js
+++ b/src/packet/one_pass_signature.js
@@ -46,16 +46,20 @@ class OnePassSignaturePacket {
* A one-octet signature type.
* Signature types are described in
* {@link https://tools.ietf.org/html/rfc4880#section-5.2.1|RFC4880 Section 5.2.1}.
+ * @type {enums.signature}
+
*/
this.signatureType = null;
/**
* A one-octet number describing the hash algorithm used.
* @see {@link https://tools.ietf.org/html/rfc4880#section-9.4|RFC4880 9.4}
+ * @type {enums.hash}
*/
this.hashAlgorithm = null;
/**
* A one-octet number describing the public-key algorithm used.
* @see {@link https://tools.ietf.org/html/rfc4880#section-9.1|RFC4880 9.1}
+ * @type {enums.publicKey}
*/
this.publicKeyAlgorithm = null;
/** An eight-octet number holding the Key ID of the signing key. */
@@ -109,9 +113,7 @@ class OnePassSignaturePacket {
* @returns {Uint8Array} A Uint8Array representation of a one-pass signature packet.
*/
write() {
- const start = new Uint8Array([VERSION, enums.write(enums.signature, this.signatureType),
- enums.write(enums.hash, this.hashAlgorithm),
- enums.write(enums.publicKey, this.publicKeyAlgorithm)]);
+ const start = new Uint8Array([VERSION, this.signatureType, this.hashAlgorithm, this.publicKeyAlgorithm]);
const end = new Uint8Array([this.flags]);
diff --git a/src/packet/public_key.js b/src/packet/public_key.js
index 7c273e6e..4a1ef788 100644
--- a/src/packet/public_key.js
+++ b/src/packet/public_key.js
@@ -55,7 +55,7 @@ class PublicKeyPacket {
this.created = util.normalizeDate(date);
/**
* Public key algorithm.
- * @type {String}
+ * @type {enums.publicKey}
*/
this.algorithm = null;
/**
@@ -115,8 +115,7 @@ class PublicKeyPacket {
pos += 4;
// - A one-octet number denoting the public-key algorithm of this key.
- this.algorithm = enums.read(enums.publicKey, bytes[pos++]);
- const algo = enums.write(enums.publicKey, this.algorithm);
+ this.algorithm = bytes[pos++];
if (this.version === 5) {
// - A four-octet scalar octet count for the following key material.
@@ -125,7 +124,7 @@ class PublicKeyPacket {
// - A series of values comprising the key material.
try {
- const { read, publicParams } = crypto.parsePublicKeyParams(algo, bytes.subarray(pos));
+ const { read, publicParams } = crypto.parsePublicKeyParams(this.algorithm, bytes.subarray(pos));
this.publicParams = publicParams;
pos += read;
} catch (err) {
@@ -149,10 +148,9 @@ class PublicKeyPacket {
arr.push(new Uint8Array([this.version]));
arr.push(util.writeDate(this.created));
// A one-octet number denoting the public-key algorithm of this key
- const algo = enums.write(enums.publicKey, this.algorithm);
- arr.push(new Uint8Array([algo]));
+ arr.push(new Uint8Array([this.algorithm]));
- const params = crypto.serializeParams(algo, this.publicParams);
+ const params = crypto.serializeParams(this.algorithm, this.publicParams);
if (this.version === 5) {
// A four-octet scalar octet count for the following key material
arr.push(util.writeNumber(params.length, 4));
@@ -261,7 +259,7 @@ class PublicKeyPacket {
*/
getAlgorithmInfo() {
const result = {};
- result.algorithm = this.algorithm;
+ result.algorithm = enums.read(enums.publicKey, this.algorithm);
// RSA, DSA or ElGamal public modulo
const modulo = this.publicParams.n || this.publicParams.p;
if (modulo) {
diff --git a/src/packet/public_key_encrypted_session_key.js b/src/packet/public_key_encrypted_session_key.js
index 582d355d..c0bedee7 100644
--- a/src/packet/public_key_encrypted_session_key.js
+++ b/src/packet/public_key_encrypted_session_key.js
@@ -51,6 +51,10 @@ class PublicKeyEncryptedSessionKeyPacket {
this.publicKeyAlgorithm = null;
this.sessionKey = null;
+ /**
+ * Algorithm to encrypt the message with
+ * @type {enums.symmetric}
+ */
this.sessionKeyAlgorithm = null;
/** @type {Object} */
@@ -68,10 +72,8 @@ class PublicKeyEncryptedSessionKeyPacket {
throw new UnsupportedError(`Version ${this.version} of the PKESK packet is unsupported.`);
}
this.publicKeyID.read(bytes.subarray(1, bytes.length));
- this.publicKeyAlgorithm = enums.read(enums.publicKey, bytes[9]);
-
- const algo = enums.write(enums.publicKey, this.publicKeyAlgorithm);
- this.encrypted = crypto.parseEncSessionKeyParams(algo, bytes.subarray(10));
+ this.publicKeyAlgorithm = bytes[9];
+ this.encrypted = crypto.parseEncSessionKeyParams(this.publicKeyAlgorithm, bytes.subarray(10));
}
/**
@@ -80,13 +82,11 @@ class PublicKeyEncryptedSessionKeyPacket {
* @returns {Uint8Array} The Uint8Array representation.
*/
write() {
- const algo = enums.write(enums.publicKey, this.publicKeyAlgorithm);
-
const arr = [
new Uint8Array([this.version]),
this.publicKeyID.write(),
- new Uint8Array([enums.write(enums.publicKey, this.publicKeyAlgorithm)]),
- crypto.serializeParams(algo, this.encrypted)
+ new Uint8Array([this.publicKeyAlgorithm]),
+ crypto.serializeParams(this.publicKeyAlgorithm, this.encrypted)
];
return util.concatUint8Array(arr);
@@ -117,20 +117,18 @@ class PublicKeyEncryptedSessionKeyPacket {
* @async
*/
async decrypt(key) {
- const algo = enums.write(enums.publicKey, this.publicKeyAlgorithm);
- const keyAlgo = enums.write(enums.publicKey, key.algorithm);
// check that session key algo matches the secret key algo
- if (algo !== keyAlgo) {
+ if (this.publicKeyAlgorithm !== key.algorithm) {
throw new Error('Decryption error');
}
- const decoded = await crypto.publicKeyDecrypt(algo, key.publicParams, key.privateParams, this.encrypted, key.getFingerprintBytes());
+ const decoded = await crypto.publicKeyDecrypt(this.publicKeyAlgorithm, key.publicParams, key.privateParams, this.encrypted, key.getFingerprintBytes());
const checksum = decoded.subarray(decoded.length - 2);
const sessionKey = decoded.subarray(1, decoded.length - 2);
if (!util.equalsUint8Array(checksum, util.writeChecksum(sessionKey))) {
throw new Error('Decryption error');
} else {
this.sessionKey = sessionKey;
- this.sessionKeyAlgorithm = enums.read(enums.symmetric, decoded[0]);
+ this.sessionKeyAlgorithm = enums.write(enums.symmetric, decoded[0]);
}
}
}
diff --git a/src/packet/secret_key.js b/src/packet/secret_key.js
index 76584b76..c1ef8c3e 100644
--- a/src/packet/secret_key.js
+++ b/src/packet/secret_key.js
@@ -49,7 +49,7 @@ class SecretKeyPacket extends PublicKeyPacket {
this.isEncrypted = null;
/**
* S2K usage
- * @type {Integer}
+ * @type {enums.symmetric}
*/
this.s2kUsage = 0;
/**
@@ -58,13 +58,13 @@ class SecretKeyPacket extends PublicKeyPacket {
*/
this.s2k = null;
/**
- * Symmetric algorithm
- * @type {String}
+ * Symmetric algorithm to encrypt the key with
+ * @type {enums.symmetric}
*/
this.symmetric = null;
/**
- * AEAD algorithm
- * @type {String}
+ * AEAD algorithm to encrypt the key with (if AEAD protection is enabled)
+ * @type {enums.aead}
*/
this.aead = null;
/**
@@ -79,7 +79,7 @@ class SecretKeyPacket extends PublicKeyPacket {
/**
* Internal parser for private keys as specified in
* {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-5.5.3|RFC4880bis-04 section 5.5.3}
- * @param {String} bytes - Input string to read the packet from
+ * @param {Uint8Array} bytes - Input string to read the packet from
* @async
*/
async read(bytes) {
@@ -102,13 +102,11 @@ class SecretKeyPacket extends PublicKeyPacket {
// one-octet symmetric encryption algorithm.
if (this.s2kUsage === 255 || this.s2kUsage === 254 || this.s2kUsage === 253) {
this.symmetric = bytes[i++];
- this.symmetric = enums.read(enums.symmetric, this.symmetric);
// - [Optional] If string-to-key usage octet was 253, a one-octet
// AEAD algorithm.
if (this.s2kUsage === 253) {
this.aead = bytes[i++];
- this.aead = enums.read(enums.aead, this.aead);
}
// - [Optional] If string-to-key usage octet was 255, 254, or 253, a
@@ -122,7 +120,6 @@ class SecretKeyPacket extends PublicKeyPacket {
}
} else if (this.s2kUsage) {
this.symmetric = this.s2kUsage;
- this.symmetric = enums.read(enums.symmetric, this.symmetric);
}
// - [Optional] If secret data is encrypted (string-to-key usage octet
@@ -131,7 +128,7 @@ class SecretKeyPacket extends PublicKeyPacket {
if (this.s2kUsage) {
this.iv = bytes.subarray(
i,
- i + crypto.cipher[this.symmetric].blockSize
+ i + crypto.getCipher(this.symmetric).blockSize
);
i += this.iv.length;
@@ -155,8 +152,7 @@ class SecretKeyPacket extends PublicKeyPacket {
throw new Error('Key checksum mismatch');
}
try {
- const algo = enums.write(enums.publicKey, this.algorithm);
- const { privateParams } = crypto.parsePrivateKeyParams(algo, cleartext, this.publicParams);
+ const { privateParams } = crypto.parsePrivateKeyParams(this.algorithm, cleartext, this.publicParams);
this.privateParams = privateParams;
} catch (err) {
throw new Error('Error reading MPIs');
@@ -177,12 +173,12 @@ class SecretKeyPacket extends PublicKeyPacket {
// - [Optional] If string-to-key usage octet was 255, 254, or 253, a
// one- octet symmetric encryption algorithm.
if (this.s2kUsage === 255 || this.s2kUsage === 254 || this.s2kUsage === 253) {
- optionalFieldsArr.push(enums.write(enums.symmetric, this.symmetric));
+ optionalFieldsArr.push(this.symmetric);
// - [Optional] If string-to-key usage octet was 253, a one-octet
// AEAD algorithm.
if (this.s2kUsage === 253) {
- optionalFieldsArr.push(enums.write(enums.aead, this.aead));
+ optionalFieldsArr.push(this.aead);
}
// - [Optional] If string-to-key usage octet was 255, 254, or 253, a
@@ -205,8 +201,7 @@ class SecretKeyPacket extends PublicKeyPacket {
if (!this.isDummy()) {
if (!this.s2kUsage) {
- const algo = enums.write(enums.publicKey, this.algorithm);
- this.keyMaterial = crypto.serializeParams(algo, this.privateParams);
+ this.keyMaterial = crypto.serializeParams(this.algorithm, this.privateParams);
}
if (this.version === 5) {
@@ -258,7 +253,7 @@ class SecretKeyPacket extends PublicKeyPacket {
this.s2k.c = 0;
this.s2k.type = 'gnu-dummy';
this.s2kUsage = 254;
- this.symmetric = 'aes256';
+ this.symmetric = enums.symmetric.aes256;
}
/**
@@ -289,17 +284,17 @@ class SecretKeyPacket extends PublicKeyPacket {
this.s2k = new S2K(config);
this.s2k.salt = await crypto.random.getRandomBytes(8);
- const algo = enums.write(enums.publicKey, this.algorithm);
- const cleartext = crypto.serializeParams(algo, this.privateParams);
- this.symmetric = 'aes256';
+ const cleartext = crypto.serializeParams(this.algorithm, this.privateParams);
+ this.symmetric = enums.symmetric.aes256;
const key = await produceEncryptionKey(this.s2k, passphrase, this.symmetric);
- const blockLen = crypto.cipher[this.symmetric].blockSize;
- this.iv = await crypto.random.getRandomBytes(blockLen);
+
+ const { blockSize } = crypto.getCipher(this.symmetric);
+ this.iv = await crypto.random.getRandomBytes(blockSize);
if (config.aeadProtect) {
this.s2kUsage = 253;
- this.aead = 'eax';
- const mode = crypto.mode[this.aead];
+ this.aead = enums.aead.eax;
+ const mode = crypto.getAEADMode(this.aead);
const modeInstance = await mode(this.symmetric, key);
this.keyMaterial = await modeInstance.encrypt(cleartext, this.iv.subarray(0, mode.ivLength), new Uint8Array());
} else {
@@ -340,9 +335,9 @@ class SecretKeyPacket extends PublicKeyPacket {
let cleartext;
if (this.s2kUsage === 253) {
- const mode = crypto.mode[this.aead];
+ const mode = crypto.getAEADMode(this.aead);
+ const modeInstance = await mode(this.symmetric, key);
try {
- const modeInstance = await mode(this.symmetric, key);
cleartext = await modeInstance.decrypt(this.keyMaterial, this.iv.subarray(0, mode.ivLength), new Uint8Array());
} catch (err) {
if (err.message === 'Authentication tag mismatch') {
@@ -362,8 +357,7 @@ class SecretKeyPacket extends PublicKeyPacket {
}
try {
- const algo = enums.write(enums.publicKey, this.algorithm);
- const { privateParams } = crypto.parsePrivateKeyParams(algo, cleartext, this.publicParams);
+ const { privateParams } = crypto.parsePrivateKeyParams(this.algorithm, cleartext, this.publicParams);
this.privateParams = privateParams;
} catch (err) {
throw new Error('Error reading MPIs');
@@ -387,12 +381,10 @@ class SecretKeyPacket extends PublicKeyPacket {
throw new Error('Key is not decrypted');
}
- const algo = enums.write(enums.publicKey, this.algorithm);
-
let validParams;
try {
// this can throw if some parameters are undefined
- validParams = await crypto.validateParams(algo, this.publicParams, this.privateParams);
+ validParams = await crypto.validateParams(this.algorithm, this.publicParams, this.privateParams);
} catch (_) {
validParams = false;
}
@@ -402,8 +394,7 @@ class SecretKeyPacket extends PublicKeyPacket {
}
async generate(bits, curve) {
- const algo = enums.write(enums.publicKey, this.algorithm);
- const { privateParams, publicParams } = await crypto.generateParams(algo, bits, curve);
+ const { privateParams, publicParams } = await crypto.generateParams(this.algorithm, bits, curve);
this.privateParams = privateParams;
this.publicParams = publicParams;
this.isEncrypted = false;
@@ -428,10 +419,8 @@ class SecretKeyPacket extends PublicKeyPacket {
}
async function produceEncryptionKey(s2k, passphrase, algorithm) {
- return s2k.produceKey(
- passphrase,
- crypto.cipher[algorithm].keySize
- );
+ const { keySize } = crypto.getCipher(algorithm);
+ return s2k.produceKey(passphrase, keySize);
}
export default SecretKeyPacket;
diff --git a/src/packet/signature.js b/src/packet/signature.js
index 78d74c79..d0b01d0a 100644
--- a/src/packet/signature.js
+++ b/src/packet/signature.js
@@ -50,8 +50,11 @@ class SignaturePacket {
constructor() {
this.version = null;
+ /** @type {enums.signature} */
this.signatureType = null;
+ /** @type {enums.hash} */
this.hashAlgorithm = null;
+ /** @type {enums.publicKey} */
this.publicKeyAlgorithm = null;
this.signatureData = null;
@@ -170,16 +173,12 @@ class SignaturePacket {
* @async
*/
async sign(key, data, date = new Date(), 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);
-
if (key.version === 5) {
this.version = 5;
} else {
this.version = 4;
}
- const arr = [new Uint8Array([this.version, signatureType, publicKeyAlgorithm, hashAlgorithm])];
+ const arr = [new Uint8Array([this.version, this.signatureType, this.publicKeyAlgorithm, this.hashAlgorithm])];
this.created = util.normalizeDate(date);
this.issuerKeyVersion = key.version;
@@ -191,12 +190,12 @@ class SignaturePacket {
this.signatureData = util.concat(arr);
- const toHash = this.toHash(signatureType, data, detached);
- const hash = await this.hash(signatureType, data, toHash, detached);
+ const toHash = this.toHash(this.signatureType, data, detached);
+ const hash = await this.hash(this.signatureType, data, toHash, detached);
this.signedHashValue = stream.slice(stream.clone(hash), 0, 2);
const signed = async () => crypto.signature.sign(
- publicKeyAlgorithm, hashAlgorithm, key.publicParams, key.privateParams, toHash, await stream.readToEnd(hash)
+ this.publicKeyAlgorithm, this.hashAlgorithm, key.publicParams, key.privateParams, toHash, await stream.readToEnd(hash)
);
if (util.isStream(hash)) {
this.params = signed();
@@ -644,9 +643,8 @@ class SignaturePacket {
}
async hash(signatureType, data, toHash, detached = false) {
- const hashAlgorithm = enums.write(enums.hash, this.hashAlgorithm);
if (!toHash) toHash = this.toHash(signatureType, data, detached);
- return crypto.hash.digest(hashAlgorithm, toHash);
+ return crypto.hash.digest(this.hashAlgorithm, toHash);
}
/**
@@ -662,12 +660,10 @@ class SignaturePacket {
* @async
*/
async verify(key, signatureType, data, date = new Date(), detached = false, config = defaultConfig) {
- const publicKeyAlgorithm = enums.write(enums.publicKey, this.publicKeyAlgorithm);
- const hashAlgorithm = enums.write(enums.hash, this.hashAlgorithm);
if (!this.issuerKeyID.equals(key.getKeyID())) {
throw new Error('Signature was not issued by the given public key');
}
- if (publicKeyAlgorithm !== enums.write(enums.publicKey, key.algorithm)) {
+ if (this.publicKeyAlgorithm !== key.algorithm) {
throw new Error('Public key algorithm used to sign signature does not match issuer key algorithm.');
}
@@ -693,7 +689,7 @@ class SignaturePacket {
this.params = await this.params;
this[verified] = await crypto.signature.verify(
- publicKeyAlgorithm, hashAlgorithm, this.params, key.publicParams,
+ this.publicKeyAlgorithm, this.hashAlgorithm, this.params, key.publicParams,
toHash, hash
);
@@ -709,12 +705,12 @@ class SignaturePacket {
if (normDate && normDate >= this.getExpirationTime()) {
throw new Error('Signature is expired');
}
- if (config.rejectHashAlgorithms.has(hashAlgorithm)) {
- throw new Error('Insecure hash algorithm: ' + enums.read(enums.hash, hashAlgorithm).toUpperCase());
+ if (config.rejectHashAlgorithms.has(this.hashAlgorithm)) {
+ throw new Error('Insecure hash algorithm: ' + enums.read(enums.hash, this.hashAlgorithm).toUpperCase());
}
- if (config.rejectMessageHashAlgorithms.has(hashAlgorithm) &&
+ if (config.rejectMessageHashAlgorithms.has(this.hashAlgorithm) &&
[enums.signature.binary, enums.signature.text].includes(this.signatureType)) {
- throw new Error('Insecure message hash algorithm: ' + enums.read(enums.hash, hashAlgorithm).toUpperCase());
+ throw new Error('Insecure message hash algorithm: ' + enums.read(enums.hash, this.hashAlgorithm).toUpperCase());
}
this.rawNotations.forEach(({ name, critical }) => {
if (critical && (config.knownNotations.indexOf(name) < 0)) {
diff --git a/src/packet/sym_encrypted_integrity_protected_data.js b/src/packet/sym_encrypted_integrity_protected_data.js
index e081aff7..d1099a9f 100644
--- a/src/packet/sym_encrypted_integrity_protected_data.js
+++ b/src/packet/sym_encrypted_integrity_protected_data.js
@@ -80,13 +80,16 @@ class SymEncryptedIntegrityProtectedDataPacket {
/**
* Encrypt the payload in the packet.
- * @param {String} sessionKeyAlgorithm - The selected symmetric encryption algorithm to be used e.g. 'aes128'
+ * @param {enums.symmetric} sessionKeyAlgorithm - The symmetric encryption algorithm to use
* @param {Uint8Array} key - The key of cipher blocksize length to be used
* @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {Promise<Boolean>}
+ * @throws {Error} on encryption failure
* @async
*/
async encrypt(sessionKeyAlgorithm, key, config = defaultConfig) {
+ const { blockSize } = crypto.getCipher(sessionKeyAlgorithm);
+
let bytes = this.packets.write();
if (stream.isArrayStream(bytes)) bytes = await stream.readToEnd(bytes);
const prefix = await crypto.getPrefixRandom(sessionKeyAlgorithm);
@@ -96,22 +99,24 @@ class SymEncryptedIntegrityProtectedDataPacket {
const hash = await crypto.hash.sha1(stream.passiveClone(tohash));
const plaintext = util.concat([tohash, hash]);
- this.encrypted = await crypto.mode.cfb.encrypt(sessionKeyAlgorithm, key, plaintext, new Uint8Array(crypto.cipher[sessionKeyAlgorithm].blockSize), config);
+ this.encrypted = await crypto.mode.cfb.encrypt(sessionKeyAlgorithm, key, plaintext, new Uint8Array(blockSize), config);
return true;
}
/**
* Decrypts the encrypted data contained in the packet.
- * @param {String} sessionKeyAlgorithm - The selected symmetric encryption algorithm to be used e.g. 'aes128'
+ * @param {enums.symmetric} sessionKeyAlgorithm - The selected symmetric encryption algorithm to be used
* @param {Uint8Array} key - The key of cipher blocksize length to be used
* @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {Promise<Boolean>}
+ * @throws {Error} on decryption failure
* @async
*/
async decrypt(sessionKeyAlgorithm, key, config = defaultConfig) {
+ const { blockSize } = crypto.getCipher(sessionKeyAlgorithm);
let encrypted = stream.clone(this.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));
+ const decrypted = await crypto.mode.cfb.decrypt(sessionKeyAlgorithm, key, encrypted, new Uint8Array(blockSize));
// there must be a modification detection code packet as the
// last packet and everything gets hashed except the hash itself
@@ -126,7 +131,7 @@ class SymEncryptedIntegrityProtectedDataPacket {
}
return new Uint8Array();
});
- const bytes = stream.slice(tohash, crypto.cipher[sessionKeyAlgorithm].blockSize + 2); // Remove random prefix
+ const bytes = stream.slice(tohash, blockSize + 2); // Remove random prefix
let packetbytes = stream.slice(bytes, 0, -2); // Remove MDC packet
packetbytes = stream.concat([packetbytes, stream.fromAsync(() => verifyHash)]);
if (!util.isStream(encrypted) || !config.allowUnauthenticatedStream) {
diff --git a/src/packet/sym_encrypted_session_key.js b/src/packet/sym_encrypted_session_key.js
index ceaaeb9b..ca8acba3 100644
--- a/src/packet/sym_encrypted_session_key.js
+++ b/src/packet/sym_encrypted_session_key.js
@@ -46,9 +46,21 @@ class SymEncryptedSessionKeyPacket {
constructor(config = defaultConfig) {
this.version = config.aeadProtect ? 5 : 4;
this.sessionKey = null;
+ /**
+ * Algorithm to encrypt the session key with
+ * @type {enums.symmetric}
+ */
this.sessionKeyEncryptionAlgorithm = null;
- this.sessionKeyAlgorithm = 'aes256';
- this.aeadAlgorithm = enums.read(enums.aead, config.preferredAEADAlgorithm);
+ /**
+ * Algorithm to encrypt the message with
+ * @type {enums.symmetric}
+ */
+ this.sessionKeyAlgorithm = enums.symmetric.aes256;
+ /**
+ * AEAD mode to encrypt the session key with (if AEAD protection is enabled)
+ * @type {enums.aead}
+ */
+ this.aeadAlgorithm = enums.write(enums.aead, config.preferredAEADAlgorithm);
this.encrypted = null;
this.s2k = null;
this.iv = null;
@@ -69,11 +81,11 @@ class SymEncryptedSessionKeyPacket {
}
// A one-octet number describing the symmetric algorithm used.
- const algo = enums.read(enums.symmetric, bytes[offset++]);
+ const algo = bytes[offset++];
if (this.version === 5) {
// A one-octet AEAD algorithm.
- this.aeadAlgorithm = enums.read(enums.aead, bytes[offset++]);
+ this.aeadAlgorithm = bytes[offset++];
}
// A string-to-key (S2K) specifier, length as defined above.
@@ -81,7 +93,7 @@ class SymEncryptedSessionKeyPacket {
offset += this.s2k.read(bytes.subarray(offset, bytes.length));
if (this.version === 5) {
- const mode = crypto.mode[this.aeadAlgorithm];
+ const mode = crypto.getAEADMode(this.aeadAlgorithm);
// A starting initialization vector of size specified by the AEAD
// algorithm.
@@ -111,9 +123,9 @@ class SymEncryptedSessionKeyPacket {
let bytes;
if (this.version === 5) {
- bytes = util.concatUint8Array([new Uint8Array([this.version, enums.write(enums.symmetric, algo), enums.write(enums.aead, this.aeadAlgorithm)]), this.s2k.write(), this.iv, this.encrypted]);
+ bytes = util.concatUint8Array([new Uint8Array([this.version, algo, this.aeadAlgorithm]), this.s2k.write(), this.iv, this.encrypted]);
} else {
- bytes = util.concatUint8Array([new Uint8Array([this.version, enums.write(enums.symmetric, algo)]), this.s2k.write()]);
+ bytes = util.concatUint8Array([new Uint8Array([this.version, algo]), this.s2k.write()]);
if (this.encrypted !== null) {
bytes = util.concatUint8Array([bytes, this.encrypted]);
@@ -124,7 +136,7 @@ class SymEncryptedSessionKeyPacket {
}
/**
- * Decrypts the session key
+ * Decrypts the session key with the given passphrase
* @param {String} passphrase - The passphrase in string form
* @throws {Error} if decryption was not successful
* @async
@@ -134,18 +146,18 @@ class SymEncryptedSessionKeyPacket {
this.sessionKeyEncryptionAlgorithm :
this.sessionKeyAlgorithm;
- const length = crypto.cipher[algo].keySize;
- const key = await this.s2k.produceKey(passphrase, length);
+ const { blockSize, keySize } = crypto.getCipher(algo);
+ const key = await this.s2k.produceKey(passphrase, keySize);
if (this.version === 5) {
- const mode = crypto.mode[this.aeadAlgorithm];
- const adata = new Uint8Array([0xC0 | SymEncryptedSessionKeyPacket.tag, this.version, enums.write(enums.symmetric, this.sessionKeyEncryptionAlgorithm), enums.write(enums.aead, this.aeadAlgorithm)]);
+ const mode = crypto.getAEADMode(this.aeadAlgorithm);
+ const adata = new Uint8Array([0xC0 | SymEncryptedSessionKeyPacket.tag, this.version, this.sessionKeyEncryptionAlgorithm, this.aeadAlgorithm]);
const modeInstance = await mode(algo, key);
this.sessionKey = await modeInstance.decrypt(this.encrypted, this.iv, adata);
} else if (this.encrypted !== null) {
- const decrypted = await crypto.mode.cfb.decrypt(algo, key, this.encrypted, new Uint8Array(crypto.cipher[algo].blockSize));
+ const decrypted = await crypto.mode.cfb.decrypt(algo, key, this.encrypted, new Uint8Array(blockSize));
- this.sessionKeyAlgorithm = enums.read(enums.symmetric, decrypted[0]);
+ this.sessionKeyAlgorithm = enums.write(enums.symmetric, decrypted[0]);
this.sessionKey = decrypted.subarray(1, decrypted.length);
} else {
this.sessionKey = key;
@@ -153,7 +165,7 @@ class SymEncryptedSessionKeyPacket {
}
/**
- * Encrypts the session key
+ * Encrypts the session key with the given passphrase
* @param {String} passphrase - The passphrase in string form
* @param {Object} [config] - Full configuration, defaults to openpgp.config
* @throws {Error} if encryption was not successful
@@ -169,23 +181,25 @@ class SymEncryptedSessionKeyPacket {
this.s2k = new S2K(config);
this.s2k.salt = await crypto.random.getRandomBytes(8);
- const length = crypto.cipher[algo].keySize;
- const key = await this.s2k.produceKey(passphrase, length);
+ const { blockSize, keySize } = crypto.getCipher(algo);
+ const encryptionKey = await this.s2k.produceKey(passphrase, keySize);
if (this.sessionKey === null) {
this.sessionKey = await crypto.generateSessionKey(this.sessionKeyAlgorithm);
}
if (this.version === 5) {
- const mode = crypto.mode[this.aeadAlgorithm];
+ const mode = crypto.getAEADMode(this.aeadAlgorithm);
this.iv = await crypto.random.getRandomBytes(mode.ivLength); // generate new random IV
- const adata = new Uint8Array([0xC0 | SymEncryptedSessionKeyPacket.tag, this.version, enums.write(enums.symmetric, this.sessionKeyEncryptionAlgorithm), enums.write(enums.aead, this.aeadAlgorithm)]);
- const modeInstance = await mode(algo, key);
- this.encrypted = await modeInstance.encrypt(this.sessionKey, this.iv, adata);
+ const associatedData = new Uint8Array([0xC0 | SymEncryptedSessionKeyPacket.tag, this.version, this.sessionKeyEncryptionAlgorithm, this.aeadAlgorithm]);
+ const modeInstance = await mode(algo, encryptionKey);
+ this.encrypted = await modeInstance.encrypt(this.sessionKey, this.iv, associatedData);
} else {
- const algo_enum = new Uint8Array([enums.write(enums.symmetric, this.sessionKeyAlgorithm)]);
- const private_key = util.concatUint8Array([algo_enum, this.sessionKey]);
- this.encrypted = await crypto.mode.cfb.encrypt(algo, key, private_key, new Uint8Array(crypto.cipher[algo].blockSize), config);
+ const toEncrypt = util.concatUint8Array([
+ new Uint8Array([this.sessionKeyAlgorithm]),
+ this.sessionKey
+ ]);
+ this.encrypted = await crypto.mode.cfb.encrypt(algo, encryptionKey, toEncrypt, new Uint8Array(blockSize), config);
}
}
}
diff --git a/src/packet/symmetrically_encrypted_data.js b/src/packet/symmetrically_encrypted_data.js
index 265ecda7..ff4fd3d3 100644
--- a/src/packet/symmetrically_encrypted_data.js
+++ b/src/packet/symmetrically_encrypted_data.js
@@ -86,10 +86,11 @@ class SymmetricallyEncryptedDataPacket {
throw new Error('Message is not authenticated.');
}
+ const { blockSize } = crypto.getCipher(sessionKeyAlgorithm);
const encrypted = await stream.readToEnd(stream.clone(this.encrypted));
const decrypted = await crypto.mode.cfb.decrypt(sessionKeyAlgorithm, key,
- encrypted.subarray(crypto.cipher[sessionKeyAlgorithm].blockSize + 2),
- encrypted.subarray(2, crypto.cipher[sessionKeyAlgorithm].blockSize + 2)
+ encrypted.subarray(blockSize + 2),
+ encrypted.subarray(2, blockSize + 2)
);
this.packets = await PacketList.fromBinary(decrypted, allowedPackets, config);
@@ -104,12 +105,13 @@ class SymmetricallyEncryptedDataPacket {
* @throws {Error} if encryption was not successful
* @async
*/
- async encrypt(algo, key, config = defaultConfig) {
+ async encrypt(sessionKeyAlgorithm, key, config = defaultConfig) {
const data = this.packets.write();
+ const { blockSize } = crypto.getCipher(sessionKeyAlgorithm);
- const prefix = await crypto.getPrefixRandom(algo);
- const FRE = await crypto.mode.cfb.encrypt(algo, key, prefix, new Uint8Array(crypto.cipher[algo].blockSize), config);
- const ciphertext = await crypto.mode.cfb.encrypt(algo, key, data, FRE.subarray(2), config);
+ const prefix = await crypto.getPrefixRandom(sessionKeyAlgorithm);
+ const FRE = await crypto.mode.cfb.encrypt(sessionKeyAlgorithm, key, prefix, new Uint8Array(blockSize), config);
+ const ciphertext = await crypto.mode.cfb.encrypt(sessionKeyAlgorithm, key, data, FRE.subarray(2), config);
this.encrypted = util.concat([FRE, ciphertext]);
}
}
diff --git a/src/type/s2k.js b/src/type/s2k.js
index 9fcf5655..abd33e9d 100644
--- a/src/type/s2k.js
+++ b/src/type/s2k.js
@@ -38,14 +38,20 @@ class S2K {
* @param {Object} [config] - Full configuration, defaults to openpgp.config
*/
constructor(config = defaultConfig) {
- /** @type {module:enums.hash} */
- this.algorithm = 'sha256';
- /** @type {module:enums.s2k} */
+ /**
+ * Hash function identifier, or 0 for gnu-dummy keys
+ * @type {module:enums.hash | 0}
+ */
+ this.algorithm = enums.hash.sha256;
+ /**
+ * enums.s2k identifier or 'gnu-dummy'
+ * @type {String}
+ */
this.type = 'iterated';
/** @type {Integer} */
this.c = config.s2kIterationCountByte;
/** Eight bytes of salt in a binary string.
- * @type {String}
+ * @type {Uint8Array}
*/
this.salt = null;
}
@@ -59,16 +65,13 @@ class S2K {
/**
* Parsing function for a string-to-key specifier ({@link https://tools.ietf.org/html/rfc4880#section-3.7|RFC 4880 3.7}).
- * @param {String} bytes - Payload of string-to-key specifier
+ * @param {Uint8Array} bytes - Payload of string-to-key specifier
* @returns {Integer} Actual length of the object.
*/
read(bytes) {
let i = 0;
this.type = enums.read(enums.s2k, bytes[i++]);
this.algorithm = bytes[i++];
- if (this.type !== 'gnu') {
- this.algorithm = enums.read(enums.hash, this.algorithm);
- }
switch (this.type) {
case 'simple':
@@ -117,8 +120,7 @@ class S2K {
if (this.type === 'gnu-dummy') {
return new Uint8Array([101, 0, ...util.stringToUint8Array('GNU'), 1]);
}
-
- const arr = [new Uint8Array([enums.write(enums.s2k, this.type), enums.write(enums.hash, this.algorithm)])];
+ const arr = [new Uint8Array([enums.write(enums.s2k, this.type), this.algorithm])];
switch (this.type) {
case 'simple':
@@ -149,7 +151,6 @@ class S2K {
*/
async produceKey(passphrase, numBytes) {
passphrase = util.encodeUTF8(passphrase);
- const algorithm = enums.write(enums.hash, this.algorithm);
const arr = [];
let rlength = 0;
@@ -180,7 +181,7 @@ class S2K {
default:
throw new Error('Unknown s2k type.');
}
- const result = await crypto.hash.digest(algorithm, toHash);
+ const result = await crypto.hash.digest(this.algorithm, toHash);
arr.push(result);
rlength += result.length;
prefixlen++;
diff --git a/test/crypto/crypto.js b/test/crypto/crypto.js
index 5668ead4..baeb759f 100644
--- a/test/crypto/crypto.js
+++ b/test/crypto/crypto.js
@@ -233,17 +233,18 @@ module.exports = () => describe('API functional testing', function() {
});
describe('Encrypt and decrypt', function () {
- let symmAlgos = Object.keys(openpgp.enums.symmetric);
- symmAlgos = symmAlgos.filter(function(algo) {
- return algo !== 'idea' && algo !== 'plaintext';
- });
+ const symmAlgoNames = Object.keys(openpgp.enums.symmetric).filter(
+ algo => algo !== 'idea' && algo !== 'plaintext'
+ );
async function testCFB(plaintext) {
- await Promise.all(symmAlgos.map(async function(algo) {
+ await Promise.all(symmAlgoNames.map(async function(algoName) {
+ const algo = openpgp.enums.write(openpgp.enums.symmetric, algoName);
+ const { blockSize } = crypto.getCipher(algo);
const symmKey = await crypto.generateSessionKey(algo);
- const IV = new Uint8Array(crypto.cipher[algo].blockSize);
+ const IV = new Uint8Array(blockSize);
const symmencData = await crypto.mode.cfb.encrypt(algo, symmKey, util.stringToUint8Array(plaintext), IV, openpgp.config);
- const text = util.uint8ArrayToString(await crypto.mode.cfb.decrypt(algo, symmKey, symmencData, new Uint8Array(crypto.cipher[algo].blockSize)));
+ const text = util.uint8ArrayToString(await crypto.mode.cfb.decrypt(algo, symmKey, symmencData, new Uint8Array(blockSize)));
expect(text).to.equal(plaintext);
}));
}
@@ -255,7 +256,7 @@ module.exports = () => describe('API functional testing', function() {
});
it('Asymmetric using RSA with eme_pkcs1 padding', async function () {
- const symmKey = await crypto.generateSessionKey('aes256');
+ const symmKey = await crypto.generateSessionKey(openpgp.enums.symmetric.aes256);
return crypto.publicKeyEncrypt(algoRSA, RSAPublicParams, symmKey).then(RSAEncryptedData => {
return crypto.publicKeyDecrypt(
algoRSA, RSAPublicParams, RSAPrivateParams, RSAEncryptedData
@@ -266,7 +267,7 @@ module.exports = () => describe('API functional testing', function() {
});
it('Asymmetric using Elgamal with eme_pkcs1 padding', async function () {
- const symmKey = await crypto.generateSessionKey('aes256');
+ const symmKey = await crypto.generateSessionKey(openpgp.enums.symmetric.aes256);
return crypto.publicKeyEncrypt(algoElGamal, elGamalPublicParams, symmKey).then(ElgamalEncryptedData => {
return crypto.publicKeyDecrypt(
algoElGamal, elGamalPublicParams, elGamalPrivateParams, ElgamalEncryptedData
diff --git a/test/crypto/eax.js b/test/crypto/eax.js
index d137ac02..b7280b04 100644
--- a/test/crypto/eax.js
+++ b/test/crypto/eax.js
@@ -1,7 +1,7 @@
// Modified by ProtonTech AG
// Adapted from https://github.com/artjomb/cryptojs-extension/blob/8c61d159/test/eax.js
-
+const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..');
const EAX = require('../../src/crypto/mode/eax');
const util = require('../../src/util');
@@ -87,7 +87,7 @@ function testAESEAX() {
}
];
- const cipher = 'aes128';
+ const cipher = openpgp.enums.symmetric.aes128;
await Promise.all(vectors.map(async vec => {
const keyBytes = util.hexToUint8Array(vec.key);
diff --git a/test/crypto/gcm.js b/test/crypto/gcm.js
index 57aa83f4..0ffc40cb 100644
--- a/test/crypto/gcm.js
+++ b/test/crypto/gcm.js
@@ -34,16 +34,17 @@ module.exports = () => describe('Symmetric AES-GCM (experimental)', function() {
};
function testAESGCM(plaintext, nativeEncrypt, nativeDecrypt) {
- const aesAlgos = Object.keys(openpgp.enums.symmetric).filter(
- algo => algo.substr(0,3) === 'aes'
+ const aesAlgoNames = Object.keys(openpgp.enums.symmetric).filter(
+ algoName => algoName.substr(0,3) === 'aes'
);
- aesAlgos.forEach(function(algo) {
- it(algo, async function() {
+ aesAlgoNames.forEach(function(algoName) {
+ it(algoName, async function() {
const nodeCrypto = util.getNodeCrypto();
const webCrypto = util.getWebCrypto();
if (!nodeCrypto && !webCrypto) {
this.skip(); // eslint-disable-line no-invalid-this
}
+ const algo = openpgp.enums.write(openpgp.enums.symmetric, algoName);
const key = await crypto.generateSessionKey(algo);
const iv = await crypto.random.getRandomBytes(crypto.mode.gcm.ivLength);
@@ -63,7 +64,7 @@ module.exports = () => describe('Symmetric AES-GCM (experimental)', function() {
const decryptedStr = util.uint8ArrayToString(decrypted);
expect(decryptedStr).to.equal(plaintext);
- if (algo !== 'aes192') { // not implemented by webcrypto
+ if (algo !== openpgp.enums.symmetric.aes192) { // not implemented by webcrypto
// sanity check: native crypto was indeed on/off
expect(nativeEncryptSpy.called).to.equal(nativeEncrypt);
expect(nativeDecryptSpy.called).to.equal(nativeDecrypt);
diff --git a/test/crypto/ocb.js b/test/crypto/ocb.js
index 588a888d..b1cf846d 100644
--- a/test/crypto/ocb.js
+++ b/test/crypto/ocb.js
@@ -1,7 +1,7 @@
// Modified by ProtonTech AG
// Adapted from https://github.com/artjomb/cryptojs-extension/blob/8c61d159/test/eax.js
-
+const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..');
const OCB = require('../../src/crypto/mode/ocb');
const util = require('../../src/util');
@@ -115,7 +115,7 @@ module.exports = () => describe('Symmetric AES-OCB', function() {
}
];
- const cipher = 'aes128';
+ const cipher = openpgp.enums.symmetric.aes128;
await Promise.all(vectors.map(async vec => {
const msgBytes = util.hexToUint8Array(vec.P);
@@ -163,7 +163,8 @@ module.exports = () => describe('Symmetric AES-OCB', function() {
const k = new Uint8Array(keylen / 8);
k[k.length - 1] = taglen;
- const ocb = await OCB('aes' + keylen, k);
+ const algo = openpgp.enums.write(openpgp.enums.symmetric, 'aes' + keylen);
+ const ocb = await OCB(algo, k);
const c = [];
let n;
diff --git a/test/crypto/rsa.js b/test/crypto/rsa.js
index 4f4a5d55..bc1f4198 100644
--- a/test/crypto/rsa.js
+++ b/test/crypto/rsa.js
@@ -79,7 +79,7 @@ module.exports = () => describe('basic RSA cryptography', function () {
const bits = 1024;
const { publicParams, privateParams } = await crypto.generateParams(openpgp.enums.publicKey.rsaSign, bits);
const { n, e, d, p, q, u } = { ...publicParams, ...privateParams };
- const message = await crypto.generateSessionKey('aes256');
+ const message = await crypto.generateSessionKey(openpgp.enums.symmetric.aes256);
const encrypted = await crypto.publicKey.rsa.encrypt(message, n, e);
const decrypted = await crypto.publicKey.rsa.decrypt(encrypted, n, e, d, p, q, u);
expect(decrypted).to.deep.equal(message);
@@ -92,7 +92,7 @@ module.exports = () => describe('basic RSA cryptography', function () {
const bits = 1024;
const { publicParams, privateParams } = await crypto.generateParams(openpgp.enums.publicKey.rsaSign, bits);
const { n, e, d, p, q, u } = { ...publicParams, ...privateParams };
- const message = await crypto.generateSessionKey('aes256');
+ const message = await crypto.generateSessionKey(openpgp.enums.symmetric.aes256);
disableNative();
const encryptedBn = await crypto.publicKey.rsa.encrypt(message, n, e);
enableNative();
diff --git a/test/general/config.js b/test/general/config.js
index acaffbeb..b892292a 100644
--- a/test/general/config.js
+++ b/test/general/config.js
@@ -223,7 +223,7 @@ vAFM3jjrAQDgJPXsv8PqCrLGDuMa/2r6SgzYd03aw/xt1WM6hgUvhQD+J54Z
expect(encData2.constructor.tag).to.equal(openpgp.enums.packet.aeadEncryptedData);
const { packets: [compressed] } = await encrypted2.decrypt(null, passwords, null, encrypted2.fromStream, openpgp.config);
expect(compressed.constructor.tag).to.equal(openpgp.enums.packet.compressedData);
- expect(compressed.algorithm).to.equal('zip');
+ expect(compressed.algorithm).to.equal(openpgp.enums.compression.zip);
const userIDs = { name: 'Test User', email: 'text2@example.com' };
const { privateKey: key } = await openpgp.generateKey({ userIDs, format: 'object' });
diff --git a/test/general/openpgp.js b/test/general/openpgp.js
index a7e1ed8a..acdad24b 100644
--- a/test/general/openpgp.js
+++ b/test/general/openpgp.js
@@ -834,7 +834,7 @@ Be4ubVrj5KjhX2PVNEJd3XZRzaXZE2aAMQ==
-----END PGP PUBLIC KEY BLOCK-----`;
function withCompression(tests) {
- const compressionTypes = Object.keys(openpgp.enums.compression).map(k => openpgp.enums.compression[k]);
+ const compressionTypes = Object.values(openpgp.enums.compression);
compressionTypes.forEach(function (compression) {
const compressionName = openpgp.enums.read(openpgp.enums.compression, compression);
@@ -870,9 +870,9 @@ function withCompression(tests) {
}
expect(compressSpy.called).to.be.true;
- expect(compressSpy.thisValues[0].algorithm).to.equal(compressionName);
+ expect(compressSpy.thisValues[0].algorithm).to.equal(compression);
expect(decompressSpy.called).to.be.true;
- expect(decompressSpy.thisValues[0].algorithm).to.equal(compressionName);
+ expect(decompressSpy.thisValues[0].algorithm).to.equal(compression);
}
);
});
@@ -2307,7 +2307,7 @@ aOU=
it('should encrypt using custom session key and decrypt using session key', async function () {
const sessionKey = {
- data: await crypto.generateSessionKey('aes256'),
+ data: await crypto.generateSessionKey(openpgp.enums.symmetric.aes256),
algorithm: 'aes256'
};
const encOpt = {
@@ -2330,7 +2330,7 @@ aOU=
it('should encrypt using custom session key and decrypt using private key', async function () {
const sessionKey = {
- data: await crypto.generateSessionKey('aes128'),
+ data: await crypto.generateSessionKey(openpgp.enums.symmetric.aes128),
algorithm: 'aes128'
};
const encOpt = {
@@ -3481,7 +3481,7 @@ aOU=
}).then(async function (message) {
const literals = message.packets.filterByTag(openpgp.enums.packet.literalData);
expect(literals.length).to.equal(1);
- expect(literals[0].format).to.equal('binary');
+ expect(literals[0].format).to.equal(openpgp.enums.literal.binary);
expect(+literals[0].date).to.equal(+future);
const signatures = await message.verify([publicKey_2038_2045], future, undefined, openpgp.config);
expect(await stream.readToEnd(message.getLiteralData())).to.deep.equal(data);
@@ -3510,7 +3510,7 @@ aOU=
}).then(async function (message) {
const literals = message.packets.filterByTag(openpgp.enums.packet.literalData);
expect(literals.length).to.equal(1);
- expect(literals[0].format).to.equal('mime');
+ expect(literals[0].format).to.equal(openpgp.enums.literal.mime);
expect(+literals[0].date).to.equal(+future);
const signatures = await message.verify([publicKey_2038_2045], future, undefined, openpgp.config);
expect(await stream.readToEnd(message.getLiteralData())).to.deep.equal(data);
diff --git a/test/general/packet.js b/test/general/packet.js
index e86b79fc..1da54623 100644
--- a/test/general/packet.js
+++ b/test/general/packet.js
@@ -88,7 +88,7 @@ module.exports = () => describe('Packet', function() {
message.push(enc);
const key = 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]);
- const algo = 'aes256';
+ const algo = openpgp.enums.symmetric.aes256;
await enc.encrypt(algo, key, undefined, openpgp.config);
@@ -120,7 +120,7 @@ module.exports = () => describe('Packet', function() {
message.push(enc);
const key = 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]);
- const algo = 'aes256';
+ const algo = openpgp.enums.symmetric.aes256;
await enc.encrypt(algo, key, undefined, openpgp.config);
@@ -134,7 +134,7 @@ module.exports = () => describe('Packet', function() {
it('Sym. encrypted integrity protected packet', async function() {
const key = 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]);
- const algo = 'aes256';
+ const algo = openpgp.enums.symmetric.aes256;
const testText = input.createSomeMessage();
const literal = new openpgp.LiteralDataPacket();
@@ -160,7 +160,7 @@ module.exports = () => describe('Packet', function() {
try {
const key = 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]);
- const algo = 'aes256';
+ const algo = openpgp.enums.symmetric.aes256;
const testText = input.createSomeMessage();
const literal = new openpgp.LiteralDataPacket();
literal.setText(testText);
@@ -212,12 +212,12 @@ module.exports = () => describe('Packet', function() {
const testText = input.createSomeMessage();
const key = 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]);
- const algo = 'aes256';
+ const algo = openpgp.enums.symmetric.aes256;
const literal = new openpgp.LiteralDataPacket();
literal.setText(testText);
const enc = new openpgp.AEADEncryptedDataPacket();
- enc.aeadAlgorithm = 'experimentalGCM';
+ enc.aeadAlgorithm = openpgp.enums.aead.experimentalGCM;
enc.packets = new openpgp.PacketList();
enc.packets.push(literal);
const msg = new openpgp.PacketList();
@@ -254,7 +254,7 @@ module.exports = () => describe('Packet', function() {
const iv = util.hexToUint8Array('b7 32 37 9f 73 c4 92 8d e2 5f ac fe 65 17 ec 10'.replace(/\s+/g, ''));
const key = util.hexToUint8Array('86 f1 ef b8 69 52 32 9f 24 ac d3 bf d0 e5 34 6d'.replace(/\s+/g, ''));
- const algo = 'aes128';
+ const algo = openpgp.enums.symmetric.aes128;
const literal = new openpgp.LiteralDataPacket(0);
literal.setBytes(util.stringToUint8Array('Hello, world!\n'), openpgp.enums.literal.binary);
@@ -296,16 +296,15 @@ module.exports = () => describe('Packet', function() {
const parsed = new openpgp.PacketList();
await parsed.read(msgbytes, allAllowedPackets);
+ const [skesk, seip] = parsed;
- return parsed[0].decrypt('test').then(() => {
- const key = parsed[0].sessionKey;
- return parsed[1].decrypt(parsed[0].sessionKeyAlgorithm, key).then(async () => {
- const compressed = parsed[1].packets[0];
+ await skesk.decrypt('test');
+ return seip.decrypt(skesk.sessionKeyAlgorithm, skesk.sessionKey).then(async () => {
+ const compressed = seip.packets[0];
- const result = await stringify(compressed.packets[0].data);
+ const result = await stringify(compressed.packets[0].data);
- expect(result).to.equal('Hello world!\n');
- });
+ expect(result).to.equal('Hello world!\n');
});
});
@@ -319,15 +318,16 @@ module.exports = () => describe('Packet', function() {
const msg2 = new openpgp.PacketList();
enc.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]);
- enc.publicKeyAlgorithm = 'rsaEncryptSign';
- enc.sessionKeyAlgorithm = 'aes256';
+ enc.publicKeyAlgorithm = openpgp.enums.publicKey.rsaEncryptSign;
+ enc.sessionKeyAlgorithm = openpgp.enums.symmetric.aes256;
enc.publicKeyID.bytes = '12345678';
return enc.encrypt({ publicParams, getFingerprintBytes() {} }).then(async () => {
msg.push(enc);
await msg2.read(msg.write(), allAllowedPackets);
- return msg2[0].decrypt({ algorithm: 'rsaEncryptSign', publicParams, privateParams, getFingerprintBytes() {} }).then(() => {
+ const privateKey = { algorithm: openpgp.enums.publicKey.rsaEncryptSign, publicParams, privateParams, getFingerprintBytes() {} };
+ return msg2[0].decrypt(privateKey).then(() => {
expect(stringify(msg2[0].sessionKey)).to.equal(stringify(enc.sessionKey));
expect(msg2[0].sessionKeyAlgorithm).to.equal(enc.sessionKeyAlgorithm);
});
@@ -366,8 +366,8 @@ module.exports = () => describe('Packet', function() {
const secret = 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]);
enc.sessionKey = secret;
- enc.publicKeyAlgorithm = 'rsaEncryptSign';
- enc.sessionKeyAlgorithm = 'aes256';
+ enc.publicKeyAlgorithm = openpgp.enums.publicKey.rsaEncryptSign;
+ enc.sessionKeyAlgorithm = openpgp.enums.symmetric.aes256;
enc.publicKeyID.bytes = '12345678';
return enc.encrypt(key).then(() => {
@@ -447,7 +447,7 @@ module.exports = () => describe('Packet', function() {
try {
const passphrase = 'hello';
- const algo = 'aes256';
+ const algo = openpgp.enums.symmetric.aes256;
const testText = input.createSomeMessage();
const literal = new openpgp.LiteralDataPacket();
@@ -486,7 +486,7 @@ module.exports = () => describe('Packet', function() {
try {
const passphrase = 'hello';
- const algo = 'aes256';
+ const algo = openpgp.enums.symmetric.aes256;
const testText = input.createSomeMessage();
const literal = new openpgp.LiteralDataPacket();
@@ -557,7 +557,7 @@ module.exports = () => describe('Packet', function() {
try {
const passphrase = 'password';
- const algo = 'aes128';
+ const algo = openpgp.enums.symmetric.aes128;
const literal = new openpgp.LiteralDataPacket(0);
literal.setBytes(util.stringToUint8Array('Hello, world!\n'), openpgp.enums.literal.binary);
@@ -634,24 +634,24 @@ module.exports = () => describe('Packet', function() {
try {
const passphrase = 'password';
- const algo = 'aes128';
+ const algo = openpgp.enums.symmetric.aes128;
const literal = new openpgp.LiteralDataPacket(0);
literal.setBytes(util.stringToUint8Array('Hello, world!\n'), openpgp.enums.literal.binary);
literal.filename = '';
- const key_enc = new openpgp.SymEncryptedSessionKeyPacket();
- key_enc.sessionKeyAlgorithm = algo;
+ const skesk = new openpgp.SymEncryptedSessionKeyPacket();
+ skesk.sessionKeyAlgorithm = algo;
const enc = new openpgp.AEADEncryptedDataPacket();
enc.packets = new openpgp.PacketList();
enc.packets.push(literal);
- enc.aeadAlgorithm = key_enc.aeadAlgorithm = 'ocb';
+ enc.aeadAlgorithm = skesk.aeadAlgorithm = openpgp.enums.aead.ocb;
const msg = new openpgp.PacketList();
- msg.push(key_enc);
+ msg.push(skesk);
msg.push(enc);
- await key_enc.encrypt(passphrase, openpgp.config);
+ await skesk.encrypt(passphrase, openpgp.config);
- const key = key_enc.sessionKey;
+ const key = skesk.sessionKey;
await enc.encrypt(algo, key, undefined, openpgp.config);
const data = msg.write();
@@ -840,7 +840,7 @@ V+HOQJQxXJkVRYa3QrFUehiMzTeqqMdgC6ZqJy7+
const secretKeyPacket = new openpgp.SecretKeyPacket();
secretKeyPacket.privateParams = privateParams;
secretKeyPacket.publicParams = publicParams;
- secretKeyPacket.algorithm = 'rsaSign';
+ secretKeyPacket.algorithm = openpgp.enums.publicKey.rsaSign;
secretKeyPacket.isEncrypted = false;
await secretKeyPacket.encrypt('hello', { ...openpgp.config, aeadProtect: true });
expect(secretKeyPacket.s2kUsage).to.equal(253);
@@ -864,7 +864,7 @@ V+HOQJQxXJkVRYa3QrFUehiMzTeqqMdgC6ZqJy7+
packet.privateParams = { key: new Uint8Array([1, 2, 3]) };
packet.publicParams = { pubKey: new Uint8Array([4, 5, 6]) };
- packet.algorithm = 'rsaSign';
+ packet.algorithm = openpgp.enums.publicKey.rsaSign;
packet.isEncrypted = false;
packet.s2kUsage = 0;
@@ -896,7 +896,7 @@ V+HOQJQxXJkVRYa3QrFUehiMzTeqqMdgC6ZqJy7+
const secretKeyPacket = new openpgp.SecretKeyPacket();
secretKeyPacket.privateParams = privateParams;
secretKeyPacket.publicParams = publicParams;
- secretKeyPacket.algorithm = 'rsaSign';
+ secretKeyPacket.algorithm = openpgp.enums.publicKey.rsaSign;
secretKeyPacket.isEncrypted = false;
await secretKeyPacket.encrypt('hello', { ...openpgp.config, aeadProtect: false });
expect(secretKeyPacket.s2kUsage).to.equal(254);
@@ -917,7 +917,7 @@ V+HOQJQxXJkVRYa3QrFUehiMzTeqqMdgC6ZqJy7+
key.publicParams = publicParams;
key.privateParams = privateParams;
- key.algorithm = 'rsaSign';
+ key.algorithm = openpgp.enums.publicKey.rsaSign;
await key.computeFingerprintAndKeyID();
const signed = new openpgp.PacketList();
diff --git a/test/typescript/definitions.ts b/test/typescript/definitions.ts
index 10d169c4..deeedba0 100644
--- a/test/typescript/definitions.ts
+++ b/test/typescript/definitions.ts
@@ -68,7 +68,7 @@ import {
// Encrypt text message (armored)
const text = 'hello';
- const textMessage = await createMessage({ text: 'hello' });
+ const textMessage = await createMessage({ text: 'hello', format: 'text' });
const encryptedArmor: string = await encrypt({ encryptionKeys: publicKeys, message: textMessage });
expect(encryptedArmor).to.include('-----BEGIN PGP MESSAGE-----');