Skip to content

Commit

Permalink
refactor: remove EncryptError and DecryptError (#11427)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jack-Works committed Feb 22, 2024
1 parent a7aacec commit 2f0c6d0
Show file tree
Hide file tree
Showing 11 changed files with 29 additions and 88 deletions.
5 changes: 5 additions & 0 deletions .changeset/flat-pants-fry.md
@@ -0,0 +1,5 @@
---
'@masknet/encryption': minor
---

remove EncryptError and DecryptError
28 changes: 14 additions & 14 deletions packages/encryption/src/encryption/Decryption.ts
Expand Up @@ -13,23 +13,23 @@ import {
type DecryptIO,
type DecryptProgress,
DecryptProgressKind,
DecryptError,
type DecryptEphemeralECDH_PostKey,
type DecryptSuccess,
type DecryptIntermediateProgress,
DecryptIntermediateProgressKind,
type DecryptStaticECDH_PostKey,
DecryptErrorReasons,
} from './DecryptionTypes.js'
import { deriveAESByECDH_version38OrOlderExtraSteps } from './v38-ecdh.js'
export * from './DecryptionTypes.js'
const ErrorReasons = DecryptError.Reasons

type Version = PayloadParseResult.Payload['version']
export async function* decrypt(options: DecryptOptions, io: DecryptIO): AsyncIterableIterator<DecryptProgress> {
const { author: _author, encrypted: _encrypted, encryption: _encryption, version } = options.message
const { authorPublicKey: _authorPublicKey } = options.message

if (_encryption.isErr()) return yield new DecryptError(ErrorReasons.PayloadBroken, _encryption.error)
if (_encrypted.isErr()) return yield new DecryptError(ErrorReasons.PayloadBroken, _encrypted.error)
if (_encryption.isErr()) return yield new Error(DecryptErrorReasons.PayloadBroken, { cause: _encryption.error })
if (_encrypted.isErr()) return yield new Error(DecryptErrorReasons.PayloadBroken, { cause: _encrypted.error })
const encryption = _encryption.value
const encrypted = _encrypted.value

Expand All @@ -42,13 +42,13 @@ export async function* decrypt(options: DecryptOptions, io: DecryptIO): AsyncIte

if (encryption.type === 'public') {
const { AESKey, iv } = encryption
if (AESKey.isErr()) return yield new DecryptError(ErrorReasons.PayloadBroken, AESKey.error)
if (iv.isErr()) return yield new DecryptError(ErrorReasons.PayloadBroken, iv.error)
if (AESKey.isErr()) return yield new Error(DecryptErrorReasons.PayloadBroken, { cause: AESKey.error })
if (iv.isErr()) return yield new Error(DecryptErrorReasons.PayloadBroken, { cause: iv.error })
// Not calling setPostCache here. It's public post and saving key is wasting storage space.
return yield* decryptWithPostAESKey(version, AESKey.value, iv.value, encrypted, options.onDecrypted)
} else if (encryption.type === 'E2E') {
const { iv: _iv, ownersAESKeyEncrypted } = encryption
if (_iv.isErr()) return yield new DecryptError(ErrorReasons.PayloadBroken, _iv.error)
if (_iv.isErr()) return yield new Error(DecryptErrorReasons.PayloadBroken, { cause: _iv.error })
const iv = _iv.value
const author = _author.unwrapOr(None)

Expand All @@ -69,14 +69,14 @@ export async function* decrypt(options: DecryptOptions, io: DecryptIO): AsyncIte
// If we fall into this branch, it means we failed to decrypt as author.
// Since we will not ECDHE to myself when encrypting,
// it does not make sense to try the following steps (because it will never have a result).
return yield new DecryptError(ErrorReasons.CannotDecryptAsAuthor, err)
return yield new Error(DecryptErrorReasons.CannotDecryptAsAuthor, { cause: err })
}
// fall through
}
} else {
if (await hasAuthorLocalKey) {
// If the ownersAESKeyEncrypted is corrupted and we're the author, we cannot do anything to continue.
return yield new DecryptError(ErrorReasons.CannotDecryptAsAuthor, ownersAESKeyEncrypted.error)
return yield new Error(DecryptErrorReasons.CannotDecryptAsAuthor, ownersAESKeyEncrypted.error)
}
// fall through
}
Expand All @@ -96,8 +96,8 @@ export async function* decrypt(options: DecryptOptions, io: DecryptIO): AsyncIte
return io.queryAuthorPublicKey(author.unwrapOr(null), options.signal)
})
if (authorECPub.isErr())
return yield new DecryptError(ErrorReasons.AuthorPublicKeyNotFound, authorECPub.error)
if (!authorECPub.value) return yield new DecryptError(ErrorReasons.AuthorPublicKeyNotFound, undefined)
return yield new Error(DecryptErrorReasons.AuthorPublicKeyNotFound, { cause: authorECPub.error })
if (!authorECPub.value) return yield new Error(DecryptErrorReasons.AuthorPublicKeyNotFound)
return yield* v38To40StaticECDH(
version,
io,
Expand Down Expand Up @@ -218,7 +218,7 @@ async function* decryptByECDH(
return yield* parseTypedMessage(version, decrypted.value, report)
}
}
return void (yield new DecryptError(ErrorReasons.NotShareTarget, undefined))
return void (yield new Error(DecryptErrorReasons.NotShareTarget))
}

async function* decryptWithPostAESKey(
Expand All @@ -229,7 +229,7 @@ async function* decryptWithPostAESKey(
report: ((message: TypedMessage) => void) | undefined,
): AsyncIterableIterator<DecryptProgress> {
const _ = await decryptWithAES(postAESKey, iv, encrypted)
if (_.isErr()) return yield new DecryptError(ErrorReasons.DecryptFailed, _.error)
if (_.isErr()) return yield new Error(DecryptErrorReasons.DecryptFailed, { cause: _.error })
return yield* parseTypedMessage(version, _.value, report)
}

Expand All @@ -240,7 +240,7 @@ async function* parseTypedMessage(
): AsyncIterableIterator<DecryptProgress> {
const _ =
version === -37 ? decodeTypedMessageFromDocument(raw) : decodeTypedMessageFromDeprecatedFormat(raw, version)
if (_.isErr()) return yield new DecryptError(ErrorReasons.PayloadDecryptedButTypedMessageBroken, _.error)
if (_.isErr()) return yield new Error(DecryptErrorReasons.PayloadDecryptedButTypedMessageBroken, { cause: _.error })
try {
report?.(_.value)
} catch {}
Expand Down
14 changes: 1 addition & 13 deletions packages/encryption/src/encryption/DecryptionTypes.ts
Expand Up @@ -105,7 +105,7 @@ export interface DecryptIntermediateProgress {
type: DecryptProgressKind.Progress
event: DecryptIntermediateProgressKind
}
export type DecryptProgress = DecryptSuccess | DecryptError | DecryptIntermediateProgress | DecryptReportedInfo
export type DecryptProgress = DecryptSuccess | Error | DecryptIntermediateProgress | DecryptReportedInfo
export interface DecryptReportedInfo {
type: DecryptProgressKind.Info
iv?: Uint8Array
Expand All @@ -125,7 +125,6 @@ export interface DecryptSuccess {
type: DecryptProgressKind.Success
content: TypedMessage
}
// TODO: rename as DecryptErrorReasons
export enum DecryptErrorReasons {
PayloadBroken = '[@masknet/encryption] Payload is broken.',
PayloadDecryptedButTypedMessageBroken = "[@masknet/encryption] Payload decrypted, but it's inner TypedMessage is broken.",
Expand All @@ -139,14 +138,3 @@ export enum DecryptErrorReasons {
CurrentProfileDoesNotConnectedToPersona = '[@masknet/encryption] Cannot decrypt by E2E because no persona is linked with the current profile.',
NoPayloadFound = '[@masknet/encryption] No payload found in this material.',
}
export class DecryptError extends Error {
static Reasons = DecryptErrorReasons
readonly type = DecryptProgressKind.Error
constructor(
public override message: DecryptErrorReasons,
cause: any,
public recoverable = false,
) {
super(message, { cause })
}
}
8 changes: 3 additions & 5 deletions packages/encryption/src/encryption/Encryption.ts
Expand Up @@ -11,7 +11,6 @@ import { type EC_Key, encodePayload, type PayloadWellFormed } from '../payload/i
import { encryptWithAES } from '../utils/index.js'

import {
EncryptError,
EncryptErrorReasons,
type EncryptIO,
type EncryptOptions,
Expand All @@ -27,7 +26,7 @@ export async function encrypt(options: EncryptOptions, io: EncryptIO): Promise<E
const postIV = fillIV(io)
const postKey = await aes256GCM(io)
if (!postKey.usages.includes('encrypt') || !postKey.usages.includes('decrypt') || !postKey.extractable) {
throw new EncryptError(EncryptErrorReasons.AESKeyUsageError)
throw new Error(EncryptErrorReasons.AESKeyUsageError)
}

const encodedMessage = encodeMessage(options.version, options.message)
Expand Down Expand Up @@ -94,7 +93,7 @@ async function e2e_v37(
io: EncryptIO,
): Promise<[PayloadWellFormed.EndToEndEncryption, EncryptResult['e2e']]> {
const { authorPublic, postIV, postKeyEncoded } = context
if (!authorPublic.isSome()) throw new EncryptError(EncryptErrorReasons.PublicKeyNotFound)
if (!authorPublic.isSome()) throw new Error(EncryptErrorReasons.PublicKeyNotFound)

const { ephemeralKeys, getEphemeralKey } = createEphemeralKeysMap(io)
const ecdhResult = v37_addReceiver(true, { ...context, getEphemeralKey }, target, io)
Expand Down Expand Up @@ -148,8 +147,7 @@ async function e2e_v38(

async function encodeMessage(version: -38 | -37, message: SerializableTypedMessages) {
if (version === -37) return encodeTypedMessageToDocument(message)
if (!isTypedMessageText(message))
throw new EncryptError(EncryptErrorReasons.ComplexTypedMessageNotSupportedInPayload38)
if (!isTypedMessageText(message)) throw new Error(EncryptErrorReasons.ComplexTypedMessageNotSupportedInPayload38)
return encodeTypedMessageToDeprecatedFormat(message)
}
async function aes256GCM(io: EncryptIO): Promise<AESCryptoKey> {
Expand Down
9 changes: 0 additions & 9 deletions packages/encryption/src/encryption/EncryptionTypes.ts
Expand Up @@ -91,12 +91,3 @@ export enum EncryptErrorReasons {
PublicKeyNotFound = '[@masknet/encryption] Target public key not found.',
AESKeyUsageError = "[@masknet/encryption] AES key generated by IO doesn't have the correct usages or extractable property.",
}
export class EncryptError extends Error {
static Reasons = EncryptErrorReasons
constructor(
public override message: EncryptErrorReasons,
cause?: any,
) {
super(message, { cause })
}
}
2 changes: 0 additions & 2 deletions packages/encryption/src/index.ts
Expand Up @@ -13,7 +13,6 @@ export {

export {
encrypt,
EncryptError,
EncryptErrorReasons,
type EncryptOptions,
type EncryptIO,
Expand All @@ -26,7 +25,6 @@ export {

export {
decrypt,
DecryptError,
DecryptProgressKind,
DecryptIntermediateProgressKind,
DecryptErrorReasons,
Expand Down
16 changes: 6 additions & 10 deletions packages/mask/background/services/crypto/decryption.ts
Expand Up @@ -10,7 +10,6 @@ import {
type EC_Key,
decodeByNetwork,
steganographyDecodeImage,
DecryptError,
DecryptErrorReasons,
type DecryptReportedInfo,
} from '@masknet/encryption'
Expand Down Expand Up @@ -78,7 +77,7 @@ export async function* decryptWithDecoding(
decoded = decodeByNetwork(context.encryptPayloadNetwork, encoded.text)[0]
} else {
if (!context.authorHint) {
return yield new DecryptError(DecryptErrorReasons.UnrecognizedAuthor, undefined)
return yield new Error(DecryptErrorReasons.UnrecognizedAuthor)
}
const result = await steganographyDecodeImage(encoded.image, {
password: context.authorHint.toText(),
Expand All @@ -87,13 +86,13 @@ export async function* decryptWithDecoding(
if (typeof result === 'string') {
decoded = decodeByNetwork(context.encryptPayloadNetwork, result)[0]
} else if (result === null) {
return yield new DecryptError(DecryptErrorReasons.NoPayloadFound, undefined)
return yield new Error(DecryptErrorReasons.NoPayloadFound)
} else {
decoded = result
}
}

if (!decoded) return yield new DecryptError(DecryptErrorReasons.NoPayloadFound, undefined)
if (!decoded) return yield new Error(DecryptErrorReasons.NoPayloadFound)
yield* decryption(decoded, context)
}

Expand Down Expand Up @@ -172,8 +171,7 @@ async function* decryption(payload: string | Uint8Array, context: DecryptionCont
},
async *queryPostKey_version37(iv, signal) {
const author = await queryPublicKey(context.currentProfile)
if (!author)
throw new DecryptError(DecryptErrorReasons.CurrentProfileDoesNotConnectedToPersona, undefined)
if (!author) throw new Error(DecryptErrorReasons.CurrentProfileDoesNotConnectedToPersona)
yield* GUN_queryPostKey_version37(
iv,
author,
Expand All @@ -183,8 +181,7 @@ async function* decryption(payload: string | Uint8Array, context: DecryptionCont
},
async *queryPostKey_version38(iv, signal) {
const author = await queryPublicKey(context.currentProfile)
if (!author)
throw new DecryptError(DecryptErrorReasons.CurrentProfileDoesNotConnectedToPersona, undefined)
if (!author) throw new Error(DecryptErrorReasons.CurrentProfileDoesNotConnectedToPersona)
yield* GUN_queryPostKey_version39Or38(
-38,
iv,
Expand All @@ -195,8 +192,7 @@ async function* decryption(payload: string | Uint8Array, context: DecryptionCont
},
async *queryPostKey_version39(iv, signal) {
const author = await queryPublicKey(context.currentProfile)
if (!author)
throw new DecryptError(DecryptErrorReasons.CurrentProfileDoesNotConnectedToPersona, undefined)
if (!author) throw new Error(DecryptErrorReasons.CurrentProfileDoesNotConnectedToPersona)
yield* GUN_queryPostKey_version39Or38(
-39,
iv,
Expand Down
1 change: 0 additions & 1 deletion packages/shared-base/package.json
Expand Up @@ -15,7 +15,6 @@
"dependencies": {
"@dimensiondev/mask-wallet-core": "0.1.0-20211013082857-eb62e5f",
"@masknet/base": "workspace:^",
"@masknet/encryption": "workspace:^",
"@masknet/public-api": "workspace:^",
"@masknet/sdk": "workspace:^",
"@masknet/typed-message": "workspace:^",
Expand Down
30 changes: 0 additions & 30 deletions packages/shared-base/src/serializer/index.ts
Expand Up @@ -2,7 +2,6 @@ import { Typeson, TypesonPromise } from 'typeson'
import type { Serialization } from 'async-call-rpc'
import { Err, None, Ok, Some } from 'ts-results-es'
import * as BN from 'bignumber.js'
import { EncryptError, DecryptError } from '@masknet/encryption'
import { MaskEthereumProviderRpcError } from '@masknet/sdk'

import { blob, builtin, file, filelist, imagebitmap, specialNumbers } from 'typeson-registry'
Expand All @@ -27,35 +26,6 @@ function setup() {

addClass('BigNumber', BigNumber)

registerSerializableClass(
'MaskDecryptError',
(x) => x instanceof DecryptError,
(e: DecryptError) => ({
cause: (e as any).cause,
recoverable: e.recoverable,
message: e.message,
stack: e.stack,
}),
(o) => {
const e = new DecryptError(o.message, o.cause, o.recoverable)
e.stack = o.stack
return e
},
)
registerSerializableClass(
'MaskEncryptError',
(x) => x instanceof EncryptError,
(e: EncryptError) => ({
cause: e.cause,
message: e.message,
stack: e.stack,
}),
(o) => {
const e = new EncryptError(o.message, o.cause)
e.stack = o.stack
return e
},
)
registerSerializableClass(
'MaskEthereumProviderRpcError',
(x) => x instanceof MaskEthereumProviderRpcError,
Expand Down
1 change: 0 additions & 1 deletion packages/shared-base/tsconfig.json
Expand Up @@ -8,7 +8,6 @@
"include": ["./src", "./src/**/*.json"],
"references": [
{ "path": "../base/tsconfig.json" },
{ "path": "../encryption/tsconfig.json" },
{ "path": "../mask-sdk/server/tsconfig.json" },
{ "path": "../public-api/tsconfig.json" },
{ "path": "../typed-message/base/tsconfig.json" }
Expand Down
3 changes: 0 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 2f0c6d0

Please sign in to comment.