Skip to content

Commit

Permalink
feat: remove useAtChops references in code
Browse files Browse the repository at this point in the history
  • Loading branch information
murali-shris committed Oct 16, 2023
1 parent 26f378c commit 20e8a74
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 154 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,29 +65,11 @@ class SharedKeyDecryption implements AtKeyDecryption {
}
String decryptedValue = '';
try {
//# TODO remove else block once atChops once testing is good
if (atClient.getPreferences()!.useAtChops) {
final decryptionResult = atClient.atChops!
.decryptString(encryptedSharedKey, EncryptionKeyType.rsa2048);
decryptedValue = EncryptionUtil.decryptValue(
encryptedValue, decryptionResult.result,
ivBase64: atKey.metadata?.ivNonce);
} else {
var currentAtSignPrivateKey =
await (atClient.getLocalSecondary()!.getEncryptionPrivateKey());
if (currentAtSignPrivateKey == null ||
currentAtSignPrivateKey.isEmpty) {
throw AtPrivateKeyNotFoundException('Encryption private not found',
intent: Intent.fetchEncryptionPrivateKey,
exceptionScenario: ExceptionScenario.fetchEncryptionKeys);
}
decryptedValue = EncryptionUtil.decryptValue(
encryptedValue,
// ignore: deprecated_member_use_from_same_package
EncryptionUtil.decryptKey(
encryptedSharedKey, currentAtSignPrivateKey),
ivBase64: atKey.metadata?.ivNonce);
}
final decryptionResult = atClient.atChops!
.decryptString(encryptedSharedKey, EncryptionKeyType.rsa2048);
decryptedValue = EncryptionUtil.decryptValue(
encryptedValue, decryptionResult.result,
ivBase64: atKey.metadata?.ivNonce);
} on AtKeyException catch (e) {
e.stack(AtChainedException(
Intent.decryptData,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,38 +107,9 @@ abstract class AbstractAtKeyEncryption implements AtKeyEncryption {
/// - If found existing in either local or atServer, decrypt it and return
encryptedSharedKey =
defaultResponseParser.parse(encryptedSharedKey!).response;
if (_atClient.getPreferences()!.useAtChops) {
final decryptionResult = _atClient.atChops!
.decryptString(encryptedSharedKey, EncryptionKeyType.rsa2048);
return decryptionResult.result;
} else {
String? encryptionPrivateKey;
try {
encryptionPrivateKey =
await _atClient.getLocalSecondary()!.getEncryptionPrivateKey();
} on KeyNotFoundException catch (e) {
e.stack(AtChainedException(
Intent.fetchEncryptionPrivateKey,
ExceptionScenario.encryptionFailed,
'Failed to decrypt the encrypted shared key'));
rethrow;
}
try {
_logger.finer(
"Decrypting encryptedSharedKey $encryptedSharedKey using EncryptionUtil");
// ignore: deprecated_member_use_from_same_package
return EncryptionUtil.decryptKey(
encryptedSharedKey, encryptionPrivateKey!);
} on KeyNotFoundException catch (e) {
_logger.severe(
"Failed to decrypt my copy of shared symmetric key for ${atKey.sharedWith}");
e.stack(AtChainedException(
Intent.fetchEncryptionPrivateKey,
ExceptionScenario.encryptionFailed,
'Failed to decrypt the encrypted shared key'));
rethrow;
}
}
final decryptionResult = _atClient.atChops!
.decryptString(encryptedSharedKey, EncryptionKeyType.rsa2048);
return decryptionResult.result;
}

/// Create a new symmetric shared key and share it.
Expand Down
37 changes: 14 additions & 23 deletions packages/at_client/lib/src/manager/monitor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -268,29 +268,20 @@ class Monitor {
}
_logger.finer(
'Authenticating the monitor connection: from result:$fromResponse');
if (_preference.useAtChops) {
_logger.finer('Using AtChops to do the PKAM signing');
final atSigningInput = AtSigningInput(fromResponse)
..signingAlgoType = _preference.signingAlgoType
..hashingAlgoType = _preference.hashingAlgoType
..signingMode = AtSigningMode.pkam;
var signingResult = atChops!.sign(atSigningInput);
var pkamBuilder = PkamVerbBuilder()
..signingAlgo = _preference.signingAlgoType.name
..hashingAlgo = _preference.hashingAlgoType.name
..enrollmentlId = _enrollmentId
..signature = signingResult.result;
var pkamCommand = pkamBuilder.buildCommand();
_logger.finer('Sending command $pkamCommand');
await _monitorConnection!.write(pkamCommand);
} else {
var key = RSAPrivateKey.fromString(_preference.privateKey!);
var sha256signature =
key.createSHA256Signature(utf8.encode(fromResponse) as Uint8List);
var signature = base64Encode(sha256signature);
_logger.finer('Authenticating the monitor connection: pkam:$signature');
await _monitorConnection!.write('pkam:$signature\n');
}
_logger.finer('Using AtChops to do the PKAM signing');
final atSigningInput = AtSigningInput(fromResponse)
..signingAlgoType = _preference.signingAlgoType
..hashingAlgoType = _preference.hashingAlgoType
..signingMode = AtSigningMode.pkam;
var signingResult = atChops!.sign(atSigningInput);
var pkamBuilder = PkamVerbBuilder()
..signingAlgo = _preference.signingAlgoType.name
..hashingAlgo = _preference.hashingAlgoType.name
..enrollmentlId = _enrollmentId
..signature = signingResult.result;
var pkamCommand = pkamBuilder.buildCommand();
_logger.finer('Sending command $pkamCommand');
await _monitorConnection!.write(pkamCommand);

var pkamResponse = await getQueueResponse();
if (!pkamResponse.contains('success')) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,8 @@ class AtClientPreference {
/// Set to false to ignore the notifications received when device is offline.
bool fetchOfflineNotifications = true;

/// Temporary feature flag. Remove once tests are successful.
@experimental
bool useAtChops = false;
@Deprecated('No longer needed. at_chops will be used by default')
bool useAtChops = true;

/// Which version of the atProtocol this client will use.
/// Note that this is different from the version of the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,9 @@ class PutRequestTransformer
if (encryptionPrivateKey.isNull) {
throw AtPrivateKeyNotFoundException('Failed to sign the public data');
}
//# TODO remove else block once atChops once testing is good
if (_atClient.getPreferences()!.useAtChops) {
final signingResult = _atClient.atChops!
// ignore: deprecated_member_use
.signString(updateVerbBuilder.value, SigningKeyType.signingSha256);
updateVerbBuilder.dataSignature = signingResult.result;
} else {
// ignore: deprecated_member_use_from_same_package
updateVerbBuilder.dataSignature = await SignInPublicData.signInData(
updateVerbBuilder.value, encryptionPrivateKey!);
}
final atSigningInput = AtSigningInput(updateVerbBuilder.value);
final signingResult = _atClient.atChops!.sign(atSigningInput);
updateVerbBuilder.dataSignature = signingResult.result;
// Encode the public data if it contains new line characters
if (updateVerbBuilder.value.contains('\n')) {
updateVerbBuilder.value =
Expand Down
43 changes: 11 additions & 32 deletions packages/at_client/test/decryption_service_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ class MockAtLookup extends Mock implements AtLookupImpl {}

class MockLocalSecondary extends Mock implements LocalSecondary {}

class MockAtChops extends Mock implements AtChops {}

class MockAtClientImpl extends Mock implements AtClientImpl {}

class MockGetRequestTransformer extends Mock implements GetRequestTransformer {}
Expand All @@ -26,10 +28,9 @@ class MockSecondaryManager extends Mock implements SecondaryManager {}
void main() {
AtLookupImpl mockAtLookup = MockAtLookup();
AtClientImpl mockAtClientImpl = MockAtClientImpl();
AtChops mockAtChops = MockAtChops();
LocalSecondary mockLocalSecondary = MockLocalSecondary();
var atClientPreferenceWithAtChops = AtClientPreference()..useAtChops = true;
var atClientPreferenceWithoutAtChops = AtClientPreference()
..useAtChops = false;
var atClientPreferenceWithAtChops = AtClientPreference();
var lookupVerbBuilder = LookupVerbBuilder()
..atKey = 'phone.wavi'
..sharedBy = '@alice';
Expand All @@ -50,6 +51,7 @@ void main() {
.thenAnswer((_) => Future.value('dummy_encryption_public_key'));
when(() => mockLocalSecondary.executeVerb(llookupVerbBuilder))
.thenAnswer((_) async => 'dummy_shared_key');
when(() => mockAtClientImpl.atChops).thenAnswer((_) => mockAtChops);
});

group('A group of positive test mock test to verify decryption service', () {
Expand All @@ -70,17 +72,18 @@ void main() {
when(() => mockLocalSecondary.getEncryptionPrivateKey())
.thenAnswer((_) => Future.value(encryptionPrivateKey));

when(() => mockAtClientImpl.getPreferences())
.thenAnswer((_) => atClientPreferenceWithoutAtChops);
var sharedKeyDecryption = SharedKeyDecryption(mockAtClientImpl);
var result = await sharedKeyDecryption.decrypt(atKey, encryptedValue);
expect(result, 'hello');
when(() => mockAtClientImpl.getPreferences())
.thenAnswer((_) => atClientPreferenceWithAtChops);
final atChopsKeys = AtChopsKeys.create(
AtEncryptionKeyPair.create('', encryptionPrivateKey), null);
when(() => mockAtClientImpl.atChops)
.thenAnswer((_) => AtChopsImpl(atChopsKeys));
var sharedKeyDecryption = SharedKeyDecryption(mockAtClientImpl);
var result = await sharedKeyDecryption.decrypt(atKey, encryptedValue);
expect(result, 'hello');
when(() => mockAtClientImpl.getPreferences())
.thenAnswer((_) => atClientPreferenceWithAtChops);

expect(await sharedKeyDecryption.decrypt(atKey, encryptedValue), 'hello');
});
});
Expand Down Expand Up @@ -135,30 +138,6 @@ void main() {
'Failed to fetch the current atSign public key - public:publickey${mockAtClientImpl.getCurrentAtSign()!}')));
});

test(
'A test to verify exception is thrown when private encryption key is not found',
() {
var atKey = (AtKey.shared('phone', namespace: 'wavi', sharedBy: '@murali')
..sharedWith('@sitaram'))
.build();
atKey.metadata = Metadata()
..sharedKeyEnc = 'dummy_shared_key'
..pubKeyCS = 'd4f6d9483907286a0563b9fdeb01aa61';

// Returning empty string to test negative scenario
when(() => mockLocalSecondary.getEncryptionPrivateKey())
.thenAnswer((_) => Future.value(''));
when(() => mockAtClientImpl.getPreferences())
.thenAnswer((_) => atClientPreferenceWithoutAtChops);

var sharedKeyDecryption = SharedKeyDecryption(mockAtClientImpl);
expect(
() async => await sharedKeyDecryption.decrypt(atKey, '123'),
throwsA(predicate((dynamic e) =>
e is AtPrivateKeyNotFoundException &&
e.message == 'Encryption private not found')));
});

test(
'A test to verify exception is thrown when private encryption key is not found using at_chops',
() {
Expand Down
31 changes: 30 additions & 1 deletion packages/at_client/test/encryption_service_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ import 'package:at_commons/at_builders.dart';
import 'package:at_persistence_secondary_server/at_persistence_secondary_server.dart';
import 'package:mocktail/mocktail.dart';
import 'package:test/test.dart';
import 'package:at_chops/at_chops.dart';

class MockAtClientManager extends Mock implements AtClientManager {}

class MockLocalSecondary extends Mock implements LocalSecondary {}

class MockRemoteSecondary extends Mock implements RemoteSecondary {}

class MockAtChops extends Mock implements AtChops {}

class MockAtClient extends Mock implements AtClient {
@override
AtClientPreference getPreferences() {
Expand All @@ -25,6 +28,8 @@ class MockAtClient extends Mock implements AtClient {

class FakeLocalLookUpVerbBuilder extends Fake implements LLookupVerbBuilder {}

class FakeAtSigningInput extends Fake implements AtSigningInput {}

class MockCommitLogKeystore extends Mock implements CommitLogKeyStore {}

void main() {
Expand All @@ -37,6 +42,17 @@ void main() {
AtClientManager mockAtClientManager = MockAtClientManager();

registerFallbackValue(FakeLocalLookUpVerbBuilder());
AtChops mockAtChops = MockAtChops();
late AtSigningResult mockSigningResult;

setUp(() {
when(() => mockAtClient.atChops).thenAnswer((_) => mockAtChops);
when(() => mockAtClient.getLocalSecondary())
.thenAnswer((_) => mockLocalSecondary);
mockSigningResult = AtSigningResult()..result = 'mock_signing_result';
registerFallbackValue(FakeAtSigningInput());
when(() => mockAtChops.sign(any())).thenAnswer((_) => mockSigningResult);
});

group('A group of test to validate self key encryption exceptions', () {
test(
Expand Down Expand Up @@ -200,7 +216,10 @@ void main() {

when(() => mockAtClient.getLocalSecondary())
.thenAnswer((_) => mockLocalSecondary);

when(() => mockAtChops.decryptString(
encryptedSharedKey, EncryptionKeyType.rsa2048))
.thenAnswer(
(_) => (AtEncryptionResult()..result = originalSharedKey));
when(() => mockLocalSecondary
.executeVerb(any(that: LLookupEncryptedSharedKeyMatcher())))
.thenAnswer((_) => Future.value(encryptedSharedKey));
Expand Down Expand Up @@ -231,6 +250,10 @@ void main() {
.thenAnswer((_) => mockLocalSecondary);
when(() => mockAtClient.getRemoteSecondary())
.thenAnswer((_) => mockRemoteSecondary);
when(() => mockAtChops.decryptString(
encryptedSharedKey, EncryptionKeyType.rsa2048))
.thenAnswer(
(_) => (AtEncryptionResult()..result = originalSharedKey));

when(() => mockLocalSecondary.executeVerb(
any(that: LLookupEncryptedSharedKeyMatcher()))).thenAnswer((_) async {
Expand Down Expand Up @@ -347,6 +370,9 @@ void main() {
when(() => mockLocalSecondary
.executeVerb(any(that: EncryptionPublicKeyMatcher())))
.thenAnswer((_) => Future.value(encryptionPublicKey));
when(() => mockAtChops.decryptString(
encryptedSharedKey, EncryptionKeyType.rsa2048))
.thenAnswer((_) => (AtEncryptionResult()..result = sharedKey));

var encryptedValue = await sharedKeyEncryption.encrypt(atKey, value);
expect(atKey.metadata?.sharedKeyEnc.isNotNull, true);
Expand Down Expand Up @@ -381,6 +407,9 @@ void main() {
when(() => mockLocalSecondary
.executeVerb(any(that: EncryptionPublicKeyMatcher())))
.thenAnswer((_) => Future.value(encryptionPublicKey));
when(() => mockAtChops.decryptString(
encryptedSharedKey, EncryptionKeyType.rsa2048))
.thenAnswer((_) => (AtEncryptionResult()..result = sharedKey));

var encryptedValue = await sharedKeyEncryption.encrypt(atKey, value);
var decryptedSharedKey =
Expand Down
1 change: 0 additions & 1 deletion packages/at_client/test/full_stack_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ void main() {
group('Test with full client stack except mockRemoteSecondary', () {
final fullStackPrefs = AtClientPreference()
..namespace = namespace
..useAtChops = true
..isLocalStoreRequired = true
..hiveStoragePath = '$namespace/put/hive'
..commitLogPath = '$namespace/put/commitLog';
Expand Down
Loading

0 comments on commit 20e8a74

Please sign in to comment.