Skip to content

Commit

Permalink
fix: review updates
Browse files Browse the repository at this point in the history
  • Loading branch information
shetzel committed Jan 30, 2024
1 parent aca00d9 commit b9b947c
Showing 1 changed file with 22 additions and 29 deletions.
51 changes: 22 additions & 29 deletions src/crypto/crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ const IV_BYTES = {
v1: 6,
v2: 12,
};
const ENCODING: { v1: 'utf8'; v2: 'hex' } = {
const ENCODING = {
v1: 'utf8',
v2: 'hex',
};
} as const;
const KEY_SIZE = {
v1: 16,
v2: 32,
Expand All @@ -44,13 +44,12 @@ const ACCOUNT = 'local';

let cryptoLogger: Logger;
const getCryptoLogger = (): Logger => {
if (!cryptoLogger) {
cryptoLogger = Logger.childFromRoot('crypto');
}
cryptoLogger ??= Logger.childFromRoot('crypto');
return cryptoLogger;
};

type CryptoVersion = 'v1' | 'v2';
type CryptoEncoding = 'utf8' | 'hex';
type CryptoVersion = keyof typeof IV_BYTES;
let cryptoVersion: CryptoVersion;
const getCryptoVersion = (): CryptoVersion => {
if (!cryptoVersion) {
Expand All @@ -74,14 +73,7 @@ interface CredType {
password: string;
}

type DecryptConfigV1 = {
tag: string;
iv: string;
secret: string;
};
type DecryptConfigV2 = DecryptConfigV1 & { tokens: string[] };

const makeSecureBuffer = (password: string | undefined, encoding: 'utf8' | 'hex'): SecureBuffer<string> => {
const makeSecureBuffer = (password: string | undefined, encoding: CryptoEncoding): SecureBuffer<string> => {
const newSb = new SecureBuffer<string>();
newSb.consume(Buffer.from(ensure(password), encoding));
return newSb;
Expand All @@ -98,7 +90,7 @@ const keychainPromises = {
* @param service The keychain service name.
* @param account The keychain account name.
*/
getPassword(_keychain: KeyChain, service: string, account: string, encoding: 'utf8' | 'hex'): Promise<CredType> {
getPassword(_keychain: KeyChain, service: string, account: string, encoding: CryptoEncoding): Promise<CredType> {
const cacheKey = `${Global.DIR}:${service}:${account}`;
const sb = Cache.get<SecureBuffer<string>>(cacheKey);
if (!sb) {
Expand Down Expand Up @@ -211,15 +203,11 @@ export class Crypto extends AsyncOptionalCreatable<CryptoOptions> {
throw messages.createError('invalidEncryptedFormatError');
}

const tag = tokens[1];
const iv = tokens[0].substring(0, IV_BYTES[this.getCryptoVersion()] * 2);
const secret = tokens[0].substring(IV_BYTES[this.getCryptoVersion()] * 2, tokens[0].length);

// When everything is v2, we can remove the else
if (this.isV2Crypto()) {
return this.decryptV2({ tag, iv, secret, tokens });
return this.decryptV2(tokens);
} else {
return this.decryptV1({ tag, iv, secret });
return this.decryptV1(tokens);
}
}

Expand Down Expand Up @@ -345,15 +333,17 @@ export class Crypto extends AsyncOptionalCreatable<CryptoOptions> {
});
}

private decryptV1({ tag, iv, secret }: DecryptConfigV1): Optional<string> {
private decryptV1(tokens: string[]): Optional<string> {
const tag = tokens[1];
const iv = tokens[0].substring(0, IV_BYTES.v1 * 2);
const secret = tokens[0].substring(IV_BYTES.v1 * 2, tokens[0].length);

return this.key.value((buffer: Buffer) => {
const decipher = crypto.createDecipheriv(ALGO, buffer.toString('utf8'), iv);

let dec;
try {
decipher.setAuthTag(Buffer.from(tag, 'hex'));
dec = decipher.update(secret, 'hex', 'utf8');
dec += decipher.final('utf8');
return `${decipher.update(secret, 'hex', 'utf8')}${decipher.final('utf8')}`;
} catch (err) {
const error = messages.createError('authDecryptError', [(err as Error).message], [], err as Error);
const useGenericUnixKeychain =
Expand All @@ -363,11 +353,14 @@ export class Crypto extends AsyncOptionalCreatable<CryptoOptions> {
}
throw error;
}
return dec;
});
}

private decryptV2({ tag, iv, secret, tokens }: DecryptConfigV2): Optional<string> {
private decryptV2(tokens: string[]): Optional<string> {
const tag = tokens[1];
const iv = tokens[0].substring(0, IV_BYTES.v2 * 2);
const secret = tokens[0].substring(IV_BYTES.v2 * 2, tokens[0].length);

return this.key.value((buffer: Buffer) => {
let decipher = crypto.createDecipheriv(ALGO, buffer, Buffer.from(iv, 'hex'));

Expand All @@ -391,8 +384,8 @@ export class Crypto extends AsyncOptionalCreatable<CryptoOptions> {
if (this.v1KeyLength && err?.message === 'Unsupported state or unable to authenticate data') {
getCryptoLogger().debug('v2 decryption failed so trying v1 decryption');
try {
const ivLegacy = tokens[0].substring(0, IV_BYTES.v2);
const secretLegacy = tokens[0].substring(IV_BYTES.v2, tokens[0].length);
const ivLegacy = tokens[0].substring(0, IV_BYTES.v1 * 2);
const secretLegacy = tokens[0].substring(IV_BYTES.v1 * 2, tokens[0].length);
// v1 encryption uses a utf8 encoded string from the buffer
decipher = crypto.createDecipheriv(ALGO, buffer.toString('utf8'), ivLegacy);
decipher.setAuthTag(Buffer.from(tag, 'hex'));
Expand Down

2 comments on commit b9b947c

@svc-cli-bot
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logger Benchmarks - ubuntu-latest

Benchmark suite Current: b9b947c Previous: aca00d9 Ratio
Child logger creation 480040 ops/sec (±1.01%) 476196 ops/sec (±1.71%) 0.99
Logging a string on root logger 749811 ops/sec (±6.65%) 754485 ops/sec (±8.43%) 1.01
Logging an object on root logger 593063 ops/sec (±11.03%) 609462 ops/sec (±7.14%) 1.03
Logging an object with a message on root logger 10537 ops/sec (±201.06%) 8064 ops/sec (±204.21%) 0.77
Logging an object with a redacted prop on root logger 498451 ops/sec (±8.01%) 401677 ops/sec (±15.07%) 0.81
Logging a nested 3-level object on root logger 339647 ops/sec (±8.76%) 352391 ops/sec (±7.46%) 1.04

This comment was automatically generated by workflow using github-action-benchmark.

@svc-cli-bot
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logger Benchmarks - windows-latest

Benchmark suite Current: b9b947c Previous: aca00d9 Ratio
Child logger creation 322956 ops/sec (±0.85%) 325687 ops/sec (±0.96%) 1.01
Logging a string on root logger 753656 ops/sec (±5.53%) 824536 ops/sec (±4.87%) 1.09
Logging an object on root logger 536006 ops/sec (±6.53%) 633052 ops/sec (±7.12%) 1.18
Logging an object with a message on root logger 12238 ops/sec (±188.95%) 1854 ops/sec (±255.39%) 0.15
Logging an object with a redacted prop on root logger 414243 ops/sec (±31.86%) 437651 ops/sec (±14.66%) 1.06
Logging a nested 3-level object on root logger 353535 ops/sec (±5.47%) 346609 ops/sec (±5.47%) 0.98

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.