-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(cat-voices): vault crypto (#1011)
* chore: wip * feat: first iteration of AesCryptoService * feat: refactor SecureStorageVault to use CryptoService * fix: keychain clearing vault * chore: spacing in SecureStorageVault * test: AesCryptoService * chore: wip * feat: vault crypto service versioning + algorithm ID * test: fix vault tests * fix: vault singleton registration * fix: keychain adjustments * chore: benchmark crypto service * fix: Use Pbkdf2 instead of Argon2id key derivation algorithm * docs: improve docs for CryptoService, VaultCryptoService and Keychain * Update catalyst_voices/packages/catalyst_voices_models/lib/src/errors/crypto_exception.dart Co-authored-by: Dominik Toton <[email protected]> * fix: missing props in exceptions * docs: CryptoService and KeyDerivation connection * change random number to max 255 * fix: typo --------- Co-authored-by: Dominik Toton <[email protected]>
- Loading branch information
1 parent
1956ae7
commit 57c47ce
Showing
20 changed files
with
679 additions
and
322 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -298,3 +298,4 @@ xctestrun | |
xcworkspace | ||
xvfb | ||
yoroi | ||
Pbkdf2 |
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
62 changes: 62 additions & 0 deletions
62
catalyst_voices/packages/catalyst_voices_models/lib/src/errors/crypto_exception.dart
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 |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import 'package:equatable/equatable.dart'; | ||
|
||
sealed class CryptoException extends Equatable implements Exception { | ||
const CryptoException(); | ||
|
||
@override | ||
List<Object?> get props => []; | ||
} | ||
|
||
/// Usually thrown when trying to decrypt with invalid key | ||
final class CryptoAuthenticationException extends CryptoException { | ||
const CryptoAuthenticationException(); | ||
|
||
@override | ||
String toString() => 'CryptoAuthenticationException'; | ||
} | ||
|
||
/// Thrown when trying to decrypt tampered data | ||
final class CryptoDataMalformed extends CryptoException { | ||
final String? message; | ||
|
||
const CryptoDataMalformed([this.message]); | ||
|
||
@override | ||
String toString() { | ||
if (message != null) return 'CryptoDataMalformed: $message'; | ||
return 'CryptoDataMalformed'; | ||
} | ||
|
||
@override | ||
List<Object?> get props => [message]; | ||
} | ||
|
||
final class CryptoVersionUnsupported extends CryptoException { | ||
final String? message; | ||
|
||
const CryptoVersionUnsupported([this.message]); | ||
|
||
@override | ||
String toString() { | ||
if (message != null) return 'CryptoVersionUnsupported: $message'; | ||
return 'CryptoVersionUnsupported'; | ||
} | ||
|
||
@override | ||
List<Object?> get props => [message]; | ||
} | ||
|
||
final class CryptoAlgorithmUnsupported extends CryptoException { | ||
final String? message; | ||
|
||
const CryptoAlgorithmUnsupported([this.message]); | ||
|
||
@override | ||
String toString() { | ||
if (message != null) return 'CryptoAlgorithmUnsupported: $message'; | ||
return 'CryptoAlgorithmUnsupported'; | ||
} | ||
|
||
@override | ||
List<Object?> get props => [message]; | ||
} |
2 changes: 2 additions & 0 deletions
2
catalyst_voices/packages/catalyst_voices_models/lib/src/errors/errors.dart
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,2 +1,4 @@ | ||
export 'crypto_exception.dart'; | ||
export 'network_error.dart'; | ||
export 'secure_storage_error.dart'; | ||
export 'vault_exception.dart'; |
30 changes: 30 additions & 0 deletions
30
catalyst_voices/packages/catalyst_voices_models/lib/src/errors/vault_exception.dart
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 |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import 'package:equatable/equatable.dart'; | ||
|
||
sealed class VaultException extends Equatable implements Exception { | ||
const VaultException(); | ||
|
||
@override | ||
List<Object?> get props => []; | ||
} | ||
|
||
final class LockNotFoundException extends VaultException { | ||
final String? message; | ||
|
||
const LockNotFoundException([this.message]); | ||
|
||
@override | ||
String toString() { | ||
if (message != null) return 'LockNotFoundException: $message'; | ||
return 'LockNotFoundException'; | ||
} | ||
|
||
@override | ||
List<Object?> get props => [message]; | ||
} | ||
|
||
final class VaultLockedException extends VaultException { | ||
const VaultLockedException(); | ||
|
||
@override | ||
String toString() => 'VaultLockedException'; | ||
} |
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
72 changes: 72 additions & 0 deletions
72
catalyst_voices/packages/catalyst_voices_services/lib/src/crypto/crypto_service.dart
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 |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import 'package:flutter/foundation.dart'; | ||
|
||
/// An abstract interface that defines cryptographic operations such as | ||
/// key derivation, encryption, decryption, and key verification. | ||
// TODO(damian-molinski): Expose KeyDerivation interface and have it | ||
// delegate implementation | ||
abstract interface class CryptoService { | ||
/// Derives a cryptographic key from a given seed, with an optional salt. | ||
/// | ||
/// The derived key is generated based on the provided [seed], which serves | ||
/// as the primary input. Optionally, a [salt] can be used to further | ||
/// randomize the key derivation process, increasing security. | ||
/// | ||
/// - [seed]: The main input data used for key derivation. | ||
/// - [salt]: Optional salt value to randomize the derived key (can be null). | ||
/// | ||
/// Returns a [Future] that completes with the derived key as a [Uint8List]. | ||
Future<Uint8List> deriveKey( | ||
Uint8List seed, { | ||
Uint8List? salt, | ||
}); | ||
|
||
/// Verifies if a given cryptographic key is correctly derived from a seed. | ||
/// | ||
/// This method checks whether the provided [key] matches the key that would | ||
/// be derived from the given [seed]. This can be useful to verify integrity | ||
/// or correctness of the key derivation process. | ||
/// | ||
/// - [seed]: The input data used for key derivation. | ||
/// - [key]: The derived key that needs to be verified. | ||
/// | ||
/// Returns a [Future] that completes with `true` if the [key] is valid and | ||
/// correctly derived from the [seed], or `false` otherwise. | ||
Future<bool> verifyKey( | ||
Uint8List seed, { | ||
required Uint8List key, | ||
}); | ||
|
||
/// Decrypts the provided [data] using the specified cryptographic [key], | ||
/// usually build using [deriveKey]. | ||
/// | ||
/// This method takes encrypted [data] and decrypts it using the provided | ||
/// [key]. The decryption algorithm and the format of the data should be | ||
/// defined by the implementing class. | ||
/// | ||
/// - [data]: The encrypted data to be decrypted. | ||
/// - [key]: The key used for decryption. | ||
/// | ||
/// Returns a [Future] that completes with the decrypted data as a | ||
/// [Uint8List]. | ||
Future<Uint8List> decrypt( | ||
Uint8List data, { | ||
required Uint8List key, | ||
}); | ||
|
||
/// Encrypts the provided [data] using the specified cryptographic [key], | ||
/// usually build using [deriveKey]. | ||
/// | ||
/// This method takes plaintext [data] and encrypts it using the provided | ||
/// [key]. The encryption algorithm and format of the output should be defined | ||
/// by the implementing class. | ||
/// | ||
/// - [data]: The plaintext data to be encrypted. | ||
/// - [key]: The key used for encryption. | ||
/// | ||
/// Returns a [Future] that completes with the encrypted data as a | ||
/// [Uint8List]. | ||
Future<Uint8List> encrypt( | ||
Uint8List data, { | ||
required Uint8List key, | ||
}); | ||
} |
Oops, something went wrong.