Merge branch 'typescript-migration-gnus2k-refactor' into typescript-migration2

This commit is contained in:
Julia Krüger 2024-01-09 13:04:48 +01:00
commit ffd6ffbbfe
No known key found for this signature in database
GPG Key ID: B8738B09D5E94DEB
5 changed files with 31 additions and 70 deletions

View File

@ -134,7 +134,7 @@ class SecretKeyPacket extends PublicKeyPacket {
this.s2k = newS2KFromType(s2kType); this.s2k = newS2KFromType(s2kType);
i += this.s2k.read(bytes.subarray(i, bytes.length)); i += this.s2k.read(bytes.subarray(i, bytes.length));
if (this.s2k.type === 'gnu-dummy') { if (this.s2k.gnuType === 'gnu-dummy') {
return; return;
} }
} else if (this.s2kUsage) { } else if (this.s2kUsage) {
@ -253,7 +253,7 @@ class SecretKeyPacket extends PublicKeyPacket {
// - [Optional] If secret data is encrypted (string-to-key usage octet // - [Optional] If secret data is encrypted (string-to-key usage octet
// not zero), an Initial Vector (IV) of the same length as the // not zero), an Initial Vector (IV) of the same length as the
// cipher's block size. // cipher's block size.
if (this.s2kUsage && this.s2k.type !== 'gnu-dummy') { if (this.s2kUsage && this.s2k.gnuType !== 'gnu-dummy') {
optionalFieldsArr.push(...this.iv); optionalFieldsArr.push(...this.iv);
} }
@ -306,7 +306,7 @@ class SecretKeyPacket extends PublicKeyPacket {
* @returns {Boolean} * @returns {Boolean}
*/ */
isDummy() { 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 = newS2KFromType(enums.s2k.gnu, config);
this.s2k.algorithm = 0; this.s2k.algorithm = 0;
this.s2k.c = 0; this.s2k.c = 0;
this.s2k.type = 'gnu-dummy'; this.s2k.type = 'gnu';
this.s2k.gnuType = 'gnu-dummy';
this.s2kUsage = 254; this.s2kUsage = 254;
this.symmetric = enums.symmetric.aes256; this.symmetric = enums.symmetric.aes256;
} }

View File

@ -2,6 +2,8 @@ import defaultConfig from '../../config';
import enums from '../../enums'; import enums from '../../enums';
import util from '../../util'; import util from '../../util';
import crypto from '../../crypto'; import crypto from '../../crypto';
import type { default as loadArgonWasmModuleType } from 'argon2id';
import { Config } from '../../../openpgp';
const ARGON2_TYPE = 0x02; // id const ARGON2_TYPE = 0x02; // id
const ARGON2_VERSION = 0x13; const ARGON2_VERSION = 0x13;
@ -20,21 +22,21 @@ export class Argon2OutOfMemoryError extends Error {
} }
// cache argon wasm module // cache argon wasm module
let loadArgonWasmModule: Function; let loadArgonWasmModule: typeof loadArgonWasmModuleType;
let argon2Promise: Promise<Function>; let argon2Promise: ReturnType<typeof loadArgonWasmModuleType>;
// reload wasm module above this treshold, to deallocated used memory // reload wasm module above this treshold, to deallocated used memory
const ARGON2_WASM_MEMORY_THRESHOLD_RELOAD = 2 << 19; const ARGON2_WASM_MEMORY_THRESHOLD_RELOAD = 2 << 19;
class Argon2S2K { class Argon2S2K {
type: string; type: 'argon2';
salt: Uint8Array | null; private salt: Uint8Array | null;
t: number; private t: number;
p: number; private p: number;
encodedM: number; private encodedM: number;
/** /**
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
*/ */
constructor(config = defaultConfig) { constructor(config: Config) {
const { passes, parallelism, memoryExponent } = config.s2kArgon2Params; const { passes, parallelism, memoryExponent } = config.s2kArgon2Params;

View File

@ -27,9 +27,10 @@
* @module type/s2k * @module type/s2k
*/ */
import defaultConfig from '../../config'; import type { Config, enums as enumsType } from '../../../openpgp';
import crypto from '../../crypto';
import enums from '../../enums'; import enums from '../../enums';
import crypto from '../../crypto';
import { UnsupportedError } from '../../packet/packet'; import { UnsupportedError } from '../../packet/packet';
import util from '../../util'; import util from '../../util';
@ -41,7 +42,7 @@ class GenericS2K {
/** /**
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @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 * Hash function identifier, or 0 for gnu-dummy keys
* @type {module:enums.hash | 0} * @type {module:enums.hash | 0}

View File

@ -15,46 +15,14 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // 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 enums from '../../enums';
import { UnsupportedError } from '../../packet/packet'; import { UnsupportedError } from '../../packet/packet';
import util from '../../util'; import util from '../../util';
class GnuS2k { class GnuS2K {
algorithm: number; type: 'gnu' = 'gnu';
type: string; gnuType?: 'gnu-dummy' = undefined;
c: number; algorithm: number = enums.hash.sha256
/**
* @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;
}
/** /**
* Parsing function for a string-to-key specifier ({@link https://tools.ietf.org/html/rfc4880#section-3.7|RFC 4880 3.7}). * 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 i += 3; // GNU
const gnuExtType = 1000 + bytes[i++]; const gnuExtType = 1000 + bytes[i++];
if (gnuExtType === 1001) { if (gnuExtType === 1001) {
this.type = 'gnu-dummy'; this.gnuType = 'gnu-dummy';
// GnuPG extension mode 1001 -- don't write secret key at all // GnuPG extension mode 1001 -- don't write secret key at all
} else { } else {
throw new UnsupportedError('Unknown s2k gnu protection mode.'); throw new UnsupportedError('Unknown s2k gnu protection mode.');
@ -85,7 +53,7 @@ class GnuS2k {
* @returns {Uint8Array} Binary representation of s2k. * @returns {Uint8Array} Binary representation of s2k.
*/ */
write(): Uint8Array { write(): Uint8Array {
if (this.type === 'gnu-dummy') { if (this.gnuType === 'gnu-dummy') {
return new Uint8Array([101, 0, ...util.stringToUint8Array('GNU'), 1]); return new Uint8Array([101, 0, ...util.stringToUint8Array('GNU'), 1]);
} else { } else {
throw new Error('GNU s2k type not supported.'); throw new Error('GNU s2k type not supported.');
@ -101,19 +69,8 @@ class GnuS2k {
* @async * @async
*/ */
async produceKey(passphrase: string, numBytes: number): Promise<Uint8Array> { async produceKey(passphrase: string, numBytes: number): Promise<Uint8Array> {
const arr: number[] = []; throw new Error('Gnu S2K does not support producing keys');
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);
} }
} }
export default GnuS2k; export default GnuS2K;

View File

@ -1,9 +1,9 @@
import defaultConfig from '../../config';
import Argon2S2K, { Argon2OutOfMemoryError } from './argon2'; import Argon2S2K, { Argon2OutOfMemoryError } from './argon2';
import GenericS2K from './generic'; import GenericS2K from './generic';
import enums from '../../enums'; import enums from '../../enums';
import { UnsupportedError } from '../../packet/packet'; import { UnsupportedError } from '../../packet/packet';
import GnuS2K from './gnu'; import GnuS2K from './gnu';
import { Config } from '../../../openpgp';
const allowedS2KTypesForEncryption = new Set([enums.s2k.argon2, enums.s2k.iterated]); 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 * @returns {Object} New s2k object
* @throws {Error} for unknown or unsupported types * @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) { switch (type) {
case enums.s2k.gnu: case enums.s2k.gnu:
return new GnuS2K(config); return new GnuS2K();
case enums.s2k.argon2: case enums.s2k.argon2:
return new Argon2S2K(config); return new Argon2S2K(config);
case enums.s2k.iterated: case enums.s2k.iterated:
@ -35,7 +35,7 @@ export function newS2KFromType (type: number, config = defaultConfig): Argon2S2K
* @returns {Object} New s2k object * @returns {Object} New s2k object
* @throws {Error} for unknown or unsupported types * @throws {Error} for unknown or unsupported types
*/ */
export function newS2KFromConfig(config = defaultConfig) { export function newS2KFromConfig(config: Config) {
const { s2kType } = config; const { s2kType } = config;
if (!allowedS2KTypesForEncryption.has(s2kType)) { if (!allowedS2KTypesForEncryption.has(s2kType)) {