Support sending logs on password verification screen

This commit is contained in:
Neeraj Gupta 2022-08-29 16:01:25 +05:30
parent 730d656641
commit 7432689bb1
No known key found for this signature in database
GPG key ID: 3C5A1684DC1729E1
3 changed files with 90 additions and 2 deletions

View file

@ -29,6 +29,7 @@ import 'package:photos/services/memories_service.dart';
import 'package:photos/services/search_service.dart';
import 'package:photos/services/sync_service.dart';
import 'package:photos/utils/crypto_util.dart';
import 'package:photos/utils/validator_util.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:uuid/uuid.dart';
import 'package:wakelock/wakelock.dart';
@ -242,12 +243,18 @@ class Configuration {
String password,
KeyAttributes attributes,
) async {
_logger.info('Start decryptAndSaveSecrets');
validatePreVerificationStateCheck(
attributes, password, getEncryptedToken());
_logger.info('state validation done');
final kek = await CryptoUtil.deriveKey(
utf8.encode(password),
Sodium.base642bin(attributes.kekSalt),
attributes.memLimit,
attributes.opsLimit,
);
_logger.info('user-key done');
Uint8List key;
try {
key = CryptoUtil.decryptSync(
@ -256,20 +263,24 @@ class Configuration {
Sodium.base642bin(attributes.keyDecryptionNonce),
);
} catch (e) {
_logger.severe('master-key failed, incorrect password?');
throw Exception("Incorrect password");
}
_logger.info("master-key done");
await setKey(Sodium.bin2base64(key));
final secretKey = CryptoUtil.decryptSync(
Sodium.base642bin(attributes.encryptedSecretKey),
key,
Sodium.base642bin(attributes.secretKeyDecryptionNonce),
);
_logger.info("secret-key done");
await setSecretKey(Sodium.bin2base64(secretKey));
final token = CryptoUtil.openSealSync(
Sodium.base642bin(getEncryptedToken()),
Sodium.base642bin(attributes.publicKey),
secretKey,
);
_logger.info('appToken done');
await setToken(
Sodium.bin2base64(token, variant: Sodium.base64VariantUrlsafe),
);

View file

@ -3,10 +3,13 @@ import 'package:logging/logging.dart';
import 'package:photos/core/configuration.dart';
import 'package:photos/core/event_bus.dart';
import 'package:photos/events/subscription_purchased_event.dart';
import 'package:photos/models/key_attributes.dart';
import 'package:photos/ui/account/recovery_page.dart';
import 'package:photos/ui/common/dialogs.dart';
import 'package:photos/ui/common/dynamic_fab.dart';
import 'package:photos/ui/home_widget.dart';
import 'package:photos/utils/dialog_util.dart';
import 'package:photos/utils/email_util.dart';
class PasswordReentryPage extends StatefulWidget {
const PasswordReentryPage({Key key}) : super(key: key);
@ -16,6 +19,7 @@ class PasswordReentryPage extends StatefulWidget {
}
class _PasswordReentryPageState extends State<PasswordReentryPage> {
final _logger = Logger((_PasswordReentryPageState).toString());
final _passwordController = TextEditingController();
final FocusNode _passwordFocusNode = FocusNode();
String email;
@ -72,9 +76,26 @@ class _PasswordReentryPageState extends State<PasswordReentryPage> {
Configuration.instance.getKeyAttributes(),
);
} catch (e, s) {
Logger("PRP").severe("Password verification failed", e, s);
_logger.severe("Password verification failed", e, s);
await dialog.hide();
showErrorDialog(context, "Incorrect password", "Please try again");
var dialogUserChoice = await showChoiceDialog(
context,
"Incorrect password",
"Please try again",
firstAction: "Contact Support",
firstActionColor: Theme.of(context).colorScheme.primary,
secondAction: "Ok",
secondActionColor: Theme.of(context).colorScheme.primary,
);
if (dialogUserChoice == DialogUserChoice.firstChoice) {
await sendLogs(
context,
"Contact support",
"support@ente.io",
postShare: () {},
);
}
return;
}
await dialog.hide();
@ -231,4 +252,10 @@ class _PasswordReentryPageState extends State<PasswordReentryPage> {
],
);
}
void validatePreVerificationState(KeyAttributes keyAttributes) {
if (keyAttributes == null) {
throw Exception("Key Attributes can not be null");
}
}
}

View file

@ -0,0 +1,50 @@
import 'dart:convert';
import 'dart:typed_data';
import 'package:logging/logging.dart';
import 'package:photos/models/key_attributes.dart';
Logger _logger = Logger("Validator");
void validatePreVerificationStateCheck(
KeyAttributes keyAttr,
String password,
String encryptedToken,
) {
nullOrEmptyArgCheck(encryptedToken, "encryptedToken");
nullOrEmptyArgCheck(password, "userPassword");
if (keyAttr == null) {
throw ArgumentError("key Attributes can not be null");
}
nullOrEmptyArgCheck(keyAttr.kekSalt, "keySalt");
nullOrEmptyArgCheck(keyAttr.encryptedKey, "encryptedKey");
nullOrEmptyArgCheck(keyAttr.keyDecryptionNonce, "keyDecryptionNonce");
nullOrEmptyArgCheck(keyAttr.encryptedSecretKey, "encryptedSecretKey");
nullOrEmptyArgCheck(
keyAttr.secretKeyDecryptionNonce,
"secretKeyDecryptionNonce",
);
nullOrEmptyArgCheck(keyAttr.publicKey, "publicKey");
if ((keyAttr.memLimit ?? 0) <= 0 || (keyAttr.opsLimit ?? 0) <= 0) {
throw ArgumentError("Key mem/OpsLimit can not be null or <0");
}
// check password encoding issues
try {
Uint8List passwordL = utf8.encode(password);
try {
utf8.decode(passwordL);
} catch (e) {
_logger.severe("CRITICAL: password decode failed", e);
rethrow;
}
} catch (e) {
_logger.severe('CRITICAL: password encode failed');
rethrow;
}
}
void nullOrEmptyArgCheck(String value, String name) {
if (value == null || value.isEmpty) {
throw ArgumentError("Critical: $name is nullOrEmpty");
}
}