New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Beginning ofTypescript migration & S2K Gnu case refactor #1709
base: v6
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this 🙂
I left a few comments, mostly based on the usages of the s2k modules, which in turn affect some typing choices.
The types can also be stricted when dealing with e.g. enums.s2k
values, instead of using plain number
s -- we have the relevant type declarations in openpgp.d.ts.
Finally, I mentioned a logic change we'd like to make with the GnuS2K class & instantiations, but we can also work on that at a later time if it's easier 👌
src/type/s2k/gnu.ts
Outdated
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; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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; | |
} | |
type: 'gnu' = 'gnu'; | |
gnuType: 'gnu-dummy'; |
None of the rest should be needed anymore 🙂
And, after talking to Daniel, we'd also like to introduce gnuType
, instead of reassigning type = 'gnu-dummy'
, as such value that does not match a enums.s2k
.
In turn, that'd require updating some usages in the rest of the code (where we do e.g. s2k.type === 'gnu-dummy'
-> s2k.gnuType === 'gnu-dummy'
).
src/type/s2k/index.ts
Outdated
@@ -33,7 +35,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) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
export function newS2KFromConfig(config = defaultConfig) { | |
export function newS2KFromConfig(config: Config) { |
we want the caller to not forget to pass this explicitly in this case 🙂
src/type/s2k/gnu.ts
Outdated
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); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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'); |
✂️
src/type/s2k/argon2.ts
Outdated
let loadArgonWasmModule; | ||
let argon2Promise; | ||
let loadArgonWasmModule: Function; | ||
let argon2Promise: Promise<Function>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The argon2 module is typed, I'd take advantage of that
import type { default as loadArgonWasmModuleType, computeHashType } from 'argon2id';
let loadArgonWasmModule: typeof loadArgonWasmModuleType;
let argon2Promise: Promise<computeHashType>; // or `ReturnType<typeof loadArgonWasmModuleType>
src/type/s2k/argon2.ts
Outdated
type: string; | ||
salt: Uint8Array | null; | ||
t: number; | ||
p: number; | ||
encodedM: number; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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; |
I think we can be quite strict here 🙂
src/type/s2k/gnu.ts
Outdated
/** | ||
* 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 | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These docs don't apply to the new class -- I leave this just as reminder to either remove the comments, or update them 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll remove the comment
src/type/s2k/generic.ts
Outdated
/** | ||
* @param {Object} [config] - Full configuration, defaults to openpgp.config | ||
*/ | ||
constructor(s2kType, config = defaultConfig) { | ||
constructor(s2kType: number, config = defaultConfig) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
constructor(s2kType: number, config = defaultConfig) { | |
constructor(s2kType: enums.s2k.simple | enums.s2k.salted | enums.s2k.iterated, config = defaultConfig) { |
src/type/s2k/generic.ts
Outdated
algorithm: number; | ||
type: string; | ||
c: number; | ||
salt: Uint8Array | null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
algorithm: number; | |
type: string; | |
c: number; | |
salt: Uint8Array | null; | |
private algorithm: enums.hash; | |
type: enums.s2k.simple | enums.s2k.salted | enums.s2k.iterated; | |
private c: number; | |
private salt: Uint8Array | null; |
and also the getCount()
method can be private 🙂
src/type/s2k/generic.ts
Outdated
const arr = [new Uint8Array([enums.write(enums.s2k, this.type), this.algorithm])]; | ||
|
||
switch (this.type) { | ||
case 'simple': | ||
break; | ||
case 'salted': | ||
arr.push(this.salt); | ||
this.salt && arr.push(this.salt); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better to throw here (same for the 'iterated' case that follows), or I think it gives the wrong impression that the salt is optional 🙂
this.salt && arr.push(this.salt); | |
if (!salt) { throw Error('Salt was not set') } | |
arr.push(this.salt); |
src/type/s2k/gnu.ts
Outdated
import { UnsupportedError } from '../../packet/packet'; | ||
import util from '../../util'; | ||
|
||
class GnuS2k { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
class GnuS2k { | |
class GnuS2K { |
Hey 👋 We have addressed almost every comment on this PR 🙂 but I did notice one thing in |
b340608
to
b41298a
Compare
This is the beginning of the migration to Typescript. The typescript and rollup configuration are adjusted to support the incremental addition of typescript modules, so it also supports javascript moduls.
All typescript files need to be imported with it's explicit .ts file endings.