Refactor: s2k module to Typescrip

This commit is contained in:
Julia Krüger 2023-12-06 18:21:21 +01:00
parent e92b44bc84
commit 48bd1a06f0
No known key found for this signature in database
GPG Key ID: B8738B09D5E94DEB
6 changed files with 32 additions and 22 deletions

View File

@ -17,7 +17,7 @@
import * as stream from '@openpgp/web-stream-tools';
import { armor, unarmor } from './encoding/armor';
import { Argon2OutOfMemoryError } from './type/s2k';
import { Argon2OutOfMemoryError } from './type/s2k/index.ts';
import defaultConfig from './config';
import crypto from './crypto';
import enums from './enums';

View File

@ -16,7 +16,7 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import PublicKeyPacket from './public_key';
import { newS2KFromConfig, newS2KFromType } from '../type/s2k';
import { newS2KFromConfig, newS2KFromType } from '../type/s2k/index.ts';
import crypto from '../crypto';
import enums from '../enums';
import util from '../util';

View File

@ -15,7 +15,7 @@
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import { newS2KFromConfig, newS2KFromType } from '../type/s2k';
import { newS2KFromConfig, newS2KFromType } from '../type/s2k/index.ts';
import defaultConfig from '../config';
import crypto from '../crypto';
import computeHKDF from '../crypto/hkdf';

View File

@ -8,7 +8,7 @@ const ARGON2_VERSION = 0x13;
const ARGON2_SALT_SIZE = 16;
export class Argon2OutOfMemoryError extends Error {
constructor(...params) {
constructor(...params: string[]) {
super(...params);
if (Error.captureStackTrace) {
@ -20,16 +20,22 @@ export class Argon2OutOfMemoryError extends Error {
}
// cache argon wasm module
let loadArgonWasmModule;
let argon2Promise;
let loadArgonWasmModule: Function;
let argon2Promise: Promise<Function>;
// 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;
/**
* @param {Object} [config] - Full configuration, defaults to openpgp.config
*/
constructor(config = defaultConfig) {
const { passes, parallelism, memoryExponent } = config.s2kArgon2Params;
this.type = 'argon2';
@ -52,7 +58,7 @@ class Argon2S2K {
* @param {Uint8Array} bytes - Payload of argon2 string-to-key specifier
* @returns {Integer} Actual length of the object.
*/
read(bytes) {
read(bytes: Uint8Array) {
let i = 0;
this.salt = bytes.subarray(i, i + 16);
@ -69,7 +75,7 @@ class Argon2S2K {
* Serializes s2k information
* @returns {Uint8Array} Binary representation of s2k.
*/
write() {
write(): Uint8Array {
const arr = [
new Uint8Array([enums.write(enums.s2k, this.type)]),
this.salt,
@ -87,7 +93,7 @@ class Argon2S2K {
* @throws {Argon2OutOfMemoryError|Errors}
* @async
*/
async produceKey(passphrase, keySize) {
async produceKey(passphrase: string, keySize: number): Promise<Uint8Array> {
const decodedM = 2 << (this.encodedM - 1);
try {
@ -120,7 +126,7 @@ class Argon2S2K {
}
return hash;
} catch (e) {
if (e.message && (
if (e instanceof Error && e.message && (
e.message.includes('Unable to grow instance memory') || // Chrome
e.message.includes('failed to grow memory') || // Firefox
e.message.includes('WebAssembly.Memory.grow') || // Safari

View File

@ -34,10 +34,14 @@ import { UnsupportedError } from '../../packet/packet';
import util from '../../util';
class GenericS2K {
algorithm: number;
type: string;
c: number;
salt: Uint8Array | null;
/**
* @param {Object} [config] - Full configuration, defaults to openpgp.config
*/
constructor(s2kType, config = defaultConfig) {
constructor(s2kType: number, config = defaultConfig) {
/**
* Hash function identifier, or 0 for gnu-dummy keys
* @type {module:enums.hash | 0}
@ -76,7 +80,7 @@ class GenericS2K {
* @param {Uint8Array} bytes - Payload of string-to-key specifier
* @returns {Integer} Actual length of the object.
*/
read(bytes) {
read(bytes: Uint8Array): Number {
let i = 0;
this.algorithm = bytes[i++];
@ -123,7 +127,7 @@ class GenericS2K {
* Serializes s2k information
* @returns {Uint8Array} Binary representation of s2k.
*/
write() {
write(): Uint8Array {
if (this.type === 'gnu-dummy') {
return new Uint8Array([101, 0, ...util.stringToUint8Array('GNU'), 1]);
}
@ -133,10 +137,10 @@ class GenericS2K {
case 'simple':
break;
case 'salted':
arr.push(this.salt);
this.salt && arr.push(this.salt);
break;
case 'iterated':
arr.push(this.salt);
this.salt &&arr.push(this.salt);
arr.push(new Uint8Array([this.c]));
break;
case 'gnu':
@ -156,8 +160,8 @@ class GenericS2K {
* hashAlgorithm hash length
* @async
*/
async produceKey(passphrase, numBytes) {
passphrase = util.encodeUTF8(passphrase);
async produceKey(passphrase: string, numBytes: number): Promise<Uint8Array> {
const encodedPassphrase = util.encodeUTF8(passphrase);
const arr = [];
let rlength = 0;
@ -167,13 +171,13 @@ class GenericS2K {
let toHash;
switch (this.type) {
case 'simple':
toHash = util.concatUint8Array([new Uint8Array(prefixlen), passphrase]);
toHash = util.concatUint8Array([new Uint8Array(prefixlen), encodedPassphrase]);
break;
case 'salted':
toHash = util.concatUint8Array([new Uint8Array(prefixlen), this.salt, passphrase]);
toHash = util.concatUint8Array([new Uint8Array(prefixlen), this.salt, encodedPassphrase]);
break;
case 'iterated': {
const data = util.concatUint8Array([this.salt, passphrase]);
const data = util.concatUint8Array([this.salt, encodedPassphrase]);
let datalen = data.length;
const count = Math.max(this.getCount(), datalen);
toHash = new Uint8Array(prefixlen + count);

View File

@ -13,7 +13,7 @@ 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, config = defaultConfig) {
export function newS2KFromType (type: number, config = defaultConfig): Argon2S2K | GenericS2K {
switch (type) {
case enums.s2k.argon2:
return new Argon2S2K(config);
@ -33,7 +33,7 @@ export function newS2KFromType(type, config = defaultConfig) {
* @returns {Object} New s2k object
* @throws {Error} for unknown or unsupported types
*/
export function newS2KFromConfig(config) {
export function newS2KFromConfig(config = defaultConfig) {
const { s2kType } = config;
if (!allowedS2KTypesForEncryption.has(s2kType)) {