-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
fc17e9a
commit 5390403
Showing
7 changed files
with
168 additions
and
175 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,99 +1,95 @@ | ||
import { aes } from '@internxt/lib'; | ||
import { isValid } from '../utils/pgp.utils'; | ||
import { getOpenpgp } from './pgp.service'; | ||
import { isValidKey } from '../utils/pgp.utils'; | ||
import { ConfigService } from './config.service'; | ||
import { OpenpgpService } from './pgp.service'; | ||
|
||
export class Base64EncodedPrivateKeyError extends Error { | ||
class Base64EncodedPrivateKeyError extends Error { | ||
constructor() { | ||
super('Key is encoded in base64'); | ||
|
||
Object.setPrototypeOf(this, Base64EncodedPrivateKeyError.prototype); | ||
} | ||
} | ||
|
||
export class WrongIterationsToEncryptPrivateKeyError extends Error { | ||
class WrongIterationsToEncryptPrivateKeyError extends Error { | ||
constructor() { | ||
super('Key was encrypted using the wrong iterations number'); | ||
|
||
Object.setPrototypeOf(this, WrongIterationsToEncryptPrivateKeyError.prototype); | ||
} | ||
} | ||
|
||
export class CorruptedEncryptedPrivateKeyError extends Error { | ||
class CorruptedEncryptedPrivateKeyError extends Error { | ||
constructor() { | ||
super('Key is corrupted'); | ||
|
||
Object.setPrototypeOf(this, CorruptedEncryptedPrivateKeyError.prototype); | ||
} | ||
} | ||
|
||
export class KeysDoNotMatchError extends Error { | ||
class KeysDoNotMatchError extends Error { | ||
constructor() { | ||
super('Keys do not match'); | ||
|
||
Object.setPrototypeOf(this, CorruptedEncryptedPrivateKeyError.prototype); | ||
} | ||
} | ||
|
||
/** | ||
* This function validates the private key | ||
* @param privateKey The private key to validate encrypted | ||
* @param password The password used for encrypting the private key | ||
* @throws {Base64EncodedPrivateKeyError} If the PLAIN private key is base64 encoded (known issue introduced in the past) | ||
* @throws {WrongIterationsToEncryptPrivateKeyError} If the ENCRYPTED private key was encrypted using the wrong iterations number (known issue introduced in the past) | ||
* @throws {CorruptedEncryptedPrivateKeyError} If the ENCRYPTED private key is un-decryptable (corrupted) | ||
* @async | ||
*/ | ||
export async function assertPrivateKeyIsValid(privateKey: string, password: string): Promise<void> { | ||
let privateKeyDecrypted: string; | ||
|
||
try { | ||
privateKeyDecrypted = decryptPrivateKey(privateKey, password); | ||
} catch { | ||
export class KeysService { | ||
public static readonly instance: KeysService = new KeysService(); | ||
|
||
public assertPrivateKeyIsValid = async (privateKey: string, password: string): Promise<void> => { | ||
let privateKeyDecrypted: string; | ||
|
||
try { | ||
aes.decrypt(privateKey, password, 9999); | ||
privateKeyDecrypted = this.decryptPrivateKey(privateKey, password); | ||
} catch { | ||
throw new CorruptedEncryptedPrivateKeyError(); | ||
try { | ||
aes.decrypt(privateKey, password, 9999); | ||
} catch { | ||
throw new CorruptedEncryptedPrivateKeyError(); | ||
} | ||
|
||
throw new WrongIterationsToEncryptPrivateKeyError(); | ||
} | ||
|
||
throw new WrongIterationsToEncryptPrivateKeyError(); | ||
} | ||
const hasValidFormat = await isValidKey(privateKeyDecrypted); | ||
|
||
const hasValidFormat = await isValid(privateKeyDecrypted); | ||
if (!hasValidFormat) throw new Base64EncodedPrivateKeyError(); | ||
}; | ||
|
||
if (!hasValidFormat) throw new Base64EncodedPrivateKeyError(); | ||
} | ||
public decryptPrivateKey = (privateKey: string, password: string): string => { | ||
return aes.decrypt(privateKey, password); | ||
}; | ||
|
||
export function decryptPrivateKey(privateKey: string, password: string): string { | ||
return aes.decrypt(privateKey, password); | ||
} | ||
public assertValidateKeys = async (privateKey: string, publicKey: string): Promise<void> => { | ||
const publicKeyArmored = await OpenpgpService.openpgp.readKey({ armoredKey: publicKey }); | ||
const privateKeyArmored = await OpenpgpService.openpgp.readPrivateKey({ armoredKey: privateKey }); | ||
|
||
export async function assertValidateKeys(privateKey: string, publicKey: string): Promise<void> { | ||
const openpgp = await getOpenpgp(); | ||
const publicKeyArmored = await openpgp.readKey({ armoredKey: publicKey }); | ||
const privateKeyArmored = await openpgp.readPrivateKey({ armoredKey: privateKey }); | ||
|
||
const plainMessage = 'validate-keys'; | ||
const originalText = await openpgp.createMessage({ text: plainMessage }); | ||
const encryptedMessage = await openpgp.encrypt({ | ||
message: originalText, | ||
encryptionKeys: publicKeyArmored, | ||
}); | ||
|
||
const decryptedMessage = ( | ||
await openpgp.decrypt({ | ||
message: await openpgp.readMessage({ armoredMessage: encryptedMessage }), | ||
verificationKeys: publicKeyArmored, | ||
decryptionKeys: privateKeyArmored, | ||
}) | ||
).data; | ||
|
||
if (decryptedMessage !== plainMessage) { | ||
throw new KeysDoNotMatchError(); | ||
} | ||
} | ||
const plainMessage = 'validate-keys'; | ||
const originalText = await OpenpgpService.openpgp.createMessage({ text: plainMessage }); | ||
const encryptedMessage = await OpenpgpService.openpgp.encrypt({ | ||
message: originalText, | ||
encryptionKeys: publicKeyArmored, | ||
}); | ||
|
||
const decryptedMessage = ( | ||
await OpenpgpService.openpgp.decrypt({ | ||
message: await OpenpgpService.openpgp.readMessage({ armoredMessage: encryptedMessage }), | ||
verificationKeys: publicKeyArmored, | ||
decryptionKeys: privateKeyArmored, | ||
}) | ||
).data; | ||
|
||
if (decryptedMessage !== plainMessage) { | ||
throw new KeysDoNotMatchError(); | ||
} | ||
}; | ||
|
||
export function getAesInitFromEnv(): { iv: string; salt: string } { | ||
const { REACT_APP_MAGIC_IV: MAGIC_IV, REACT_APP_MAGIC_SALT: MAGIC_SALT } = process.env; | ||
public getAesInitFromEnv = (): { iv: string; salt: string } => { | ||
const MAGIC_IV = ConfigService.instance.get('REACT_APP_MAGIC_IV'); | ||
const MAGIC_SALT = ConfigService.instance.get('REACT_APP_MAGIC_SALT'); | ||
|
||
return { iv: MAGIC_IV as string, salt: MAGIC_SALT as string }; | ||
return { iv: MAGIC_IV as string, salt: MAGIC_SALT as string }; | ||
}; | ||
} |
Oops, something went wrong.