diff --git a/src/packet/secret_key.js b/src/packet/secret_key.js index d260d12d..8cdd7db6 100644 --- a/src/packet/secret_key.js +++ b/src/packet/secret_key.js @@ -134,7 +134,7 @@ class SecretKeyPacket extends PublicKeyPacket { this.s2k = newS2KFromType(s2kType); i += this.s2k.read(bytes.subarray(i, bytes.length)); - if (this.s2k.type === 'gnu-dummy') { + if (this.s2k.gnuType === 'gnu-dummy') { return; } } else if (this.s2kUsage) { @@ -253,7 +253,7 @@ class SecretKeyPacket extends PublicKeyPacket { // - [Optional] If secret data is encrypted (string-to-key usage octet // not zero), an Initial Vector (IV) of the same length as the // cipher's block size. - if (this.s2kUsage && this.s2k.type !== 'gnu-dummy') { + if (this.s2kUsage && this.s2k.gnuType !== 'gnu-dummy') { optionalFieldsArr.push(...this.iv); } @@ -306,7 +306,7 @@ class SecretKeyPacket extends PublicKeyPacket { * @returns {Boolean} */ isDummy() { - return !!(this.s2k && this.s2k.type === 'gnu-dummy'); + return !!(this.s2k && this.s2k.gnuType === 'gnu-dummy'); } /** @@ -327,7 +327,8 @@ class SecretKeyPacket extends PublicKeyPacket { this.s2k = newS2KFromType(enums.s2k.gnu, config); this.s2k.algorithm = 0; this.s2k.c = 0; - this.s2k.type = 'gnu-dummy'; + this.s2k.type = 'gnu'; + this.s2k.gnuType = 'gnu-dummy'; this.s2kUsage = 254; this.symmetric = enums.symmetric.aes256; } diff --git a/src/type/s2k/argon2.ts b/src/type/s2k/argon2.ts index 5636d608..f8421b57 100644 --- a/src/type/s2k/argon2.ts +++ b/src/type/s2k/argon2.ts @@ -2,6 +2,8 @@ import defaultConfig from '../../config'; import enums from '../../enums'; import util from '../../util'; import crypto from '../../crypto'; +import type { default as loadArgonWasmModuleType } from 'argon2id'; +import { Config } from '../../../openpgp'; const ARGON2_TYPE = 0x02; // id const ARGON2_VERSION = 0x13; @@ -20,21 +22,21 @@ export class Argon2OutOfMemoryError extends Error { } // cache argon wasm module -let loadArgonWasmModule: Function; -let argon2Promise: Promise; +let loadArgonWasmModule: typeof loadArgonWasmModuleType; +let argon2Promise: ReturnType; // reload wasm module above this treshold, to deallocated used memory const ARGON2_WASM_MEMORY_THRESHOLD_RELOAD = 2 << 19; class Argon2S2K { - type: string; - salt: Uint8Array | null; - t: number; - p: number; - encodedM: number; + type: 'argon2'; + private salt: Uint8Array | null; + private t: number; + private p: number; + private encodedM: number; /** * @param {Object} [config] - Full configuration, defaults to openpgp.config */ - constructor(config = defaultConfig) { + constructor(config: Config) { const { passes, parallelism, memoryExponent } = config.s2kArgon2Params; diff --git a/src/type/s2k/generic.ts b/src/type/s2k/generic.ts index df6bc8ea..36b9b41b 100644 --- a/src/type/s2k/generic.ts +++ b/src/type/s2k/generic.ts @@ -27,9 +27,10 @@ * @module type/s2k */ -import defaultConfig from '../../config'; -import crypto from '../../crypto'; +import type { Config, enums as enumsType } from '../../../openpgp'; import enums from '../../enums'; + +import crypto from '../../crypto'; import { UnsupportedError } from '../../packet/packet'; import util from '../../util'; @@ -41,7 +42,7 @@ class GenericS2K { /** * @param {Object} [config] - Full configuration, defaults to openpgp.config */ - constructor(s2kType: number, config = defaultConfig) { + constructor(s2kType: enumsType.s2k.simple | enumsType.s2k.salted | enumsType.s2k.iterated, config: Config) { /** * Hash function identifier, or 0 for gnu-dummy keys * @type {module:enums.hash | 0} diff --git a/src/type/s2k/gnu.ts b/src/type/s2k/gnu.ts index cdbe3154..2fbceb10 100644 --- a/src/type/s2k/gnu.ts +++ b/src/type/s2k/gnu.ts @@ -15,46 +15,14 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -/** - * Implementation of the String-to-key specifier - * - * {@link https://tools.ietf.org/html/rfc4880#section-3.7|RFC4880 3.7}: - * String-to-key (S2K) specifiers are used to convert passphrase strings - * into symmetric-key encryption/decryption keys. They are used in two - * places, currently: to encrypt the secret part of private keys in the - * private keyring, and to convert passphrases to encryption keys for - * symmetrically encrypted messages. - * @module type/s2k - */ - -import defaultConfig from '../../config'; import enums from '../../enums'; import { UnsupportedError } from '../../packet/packet'; import util from '../../util'; -class GnuS2k { - algorithm: number; - type: string; - c: number; - /** - * @param {Object} [config] - Full configuration, defaults to openpgp.config - */ - constructor(config = defaultConfig) { - /** - * 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 = 'gnu'; - /** - * @type {Integer} - */ - this.c = config.s2kIterationCountByte; - } +class GnuS2K { + type: 'gnu' = 'gnu'; + gnuType?: 'gnu-dummy' = undefined; + algorithm: number = enums.hash.sha256 /** * Parsing function for a string-to-key specifier ({@link https://tools.ietf.org/html/rfc4880#section-3.7|RFC 4880 3.7}). @@ -68,7 +36,7 @@ class GnuS2k { i += 3; // GNU const gnuExtType = 1000 + bytes[i++]; if (gnuExtType === 1001) { - this.type = 'gnu-dummy'; + this.gnuType = 'gnu-dummy'; // GnuPG extension mode 1001 -- don't write secret key at all } else { throw new UnsupportedError('Unknown s2k gnu protection mode.'); @@ -85,7 +53,7 @@ class GnuS2k { * @returns {Uint8Array} Binary representation of s2k. */ write(): Uint8Array { - if (this.type === 'gnu-dummy') { + if (this.gnuType === 'gnu-dummy') { return new Uint8Array([101, 0, ...util.stringToUint8Array('GNU'), 1]); } else { throw new Error('GNU s2k type not supported.'); @@ -101,19 +69,8 @@ class GnuS2k { * @async */ async produceKey(passphrase: string, numBytes: number): Promise { - const arr: number[] = []; - let rlength = 0; - - while (rlength < numBytes) { - if (this.type !== 'gnu') { - throw new Error('Unknown s2k type.'); - } else { - throw new Error('GNU s2k type not supported.'); - } - } - - return util.concatUint8Array(arr).subarray(0, numBytes); + throw new Error('Gnu S2K does not support producing keys'); } } -export default GnuS2k; +export default GnuS2K; diff --git a/src/type/s2k/index.ts b/src/type/s2k/index.ts index 9b5d23e4..7fd8059a 100644 --- a/src/type/s2k/index.ts +++ b/src/type/s2k/index.ts @@ -1,9 +1,9 @@ -import defaultConfig from '../../config'; import Argon2S2K, { Argon2OutOfMemoryError } from './argon2'; import GenericS2K from './generic'; import enums from '../../enums'; import { UnsupportedError } from '../../packet/packet'; import GnuS2K from './gnu'; +import { Config } from '../../../openpgp'; const allowedS2KTypesForEncryption = new Set([enums.s2k.argon2, enums.s2k.iterated]); @@ -14,10 +14,10 @@ const allowedS2KTypesForEncryption = new Set([enums.s2k.argon2, enums.s2k.iterat * @returns {Object} New s2k object * @throws {Error} for unknown or unsupported types */ -export function newS2KFromType (type: number, config = defaultConfig): Argon2S2K | GenericS2K | GnuS2K { +export function newS2KFromType (type: number, config: Config): Argon2S2K | GenericS2K | GnuS2K { switch (type) { case enums.s2k.gnu: - return new GnuS2K(config); + return new GnuS2K(); case enums.s2k.argon2: return new Argon2S2K(config); case enums.s2k.iterated: @@ -35,7 +35,7 @@ export function newS2KFromType (type: number, config = defaultConfig): Argon2S2K * @returns {Object} New s2k object * @throws {Error} for unknown or unsupported types */ -export function newS2KFromConfig(config = defaultConfig) { +export function newS2KFromConfig(config: Config) { const { s2kType } = config; if (!allowedS2KTypesForEncryption.has(s2kType)) {