Skip to content

Commit

Permalink
feat: add decryption (wip)
Browse files Browse the repository at this point in the history
  • Loading branch information
dufkan committed May 24, 2023
1 parent f5fd601 commit 293ef69
Show file tree
Hide file tree
Showing 31 changed files with 1,533 additions and 64 deletions.
43 changes: 43 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "meesign-client",
"request": "launch",
"type": "dart"
},
{
"name": "meesign-client (profile mode)",
"request": "launch",
"type": "dart",
"flutterMode": "profile"
},
{
"name": "meesign-client (release mode)",
"request": "launch",
"type": "dart",
"flutterMode": "release"
},
{
"name": "meesign_core",
"cwd": "meesign_core",
"request": "launch",
"type": "dart"
},
{
"name": "meesign_native",
"cwd": "meesign_native",
"request": "launch",
"type": "dart"
},
{
"name": "meesign_network",
"cwd": "meesign_network",
"request": "launch",
"type": "dart"
}
]
}
5 changes: 4 additions & 1 deletion lib/app_container.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ class AppContainer {
late final GroupRepository groupRepository;
late final FileRepository fileRepository;
late final ChallengeRepository challengeRepository;
late final DecryptRepository decryptRepository;

final bool allowBadCerts = const bool.fromEnvironment('ALLOW_BAD_CERTS');
final bool allowBadCerts = true; //const bool.fromEnvironment('ALLOW_BAD_CERTS');

AppContainer({required this.appDirectory})
: database = Database(appDirectory);
Expand All @@ -48,6 +49,8 @@ class AppContainer {
dispatcher, taskSource, taskDao, fileStore, groupRepository);
challengeRepository =
ChallengeRepository(taskSource, taskDao, groupRepository);
decryptRepository =
DecryptRepository(taskSource, taskDao, groupRepository);

Logger()
.observeErrors()
Expand Down
133 changes: 129 additions & 4 deletions lib/ui/home_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ class GroupTile extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text('Threshold: $threshold / ${members.length}'),
Text('Purpose: ${['Sign PDF', 'Log In'][keyType.index]}'),
Text('Purpose: ${['Sign PDF', 'Log In', 'Decrypt'][keyType.index]}'),
],
),
Container(
Expand Down Expand Up @@ -441,6 +441,54 @@ class LogInSubPage extends StatelessWidget {
}
}

class DecryptSubPage extends StatelessWidget {
const DecryptSubPage({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return Consumer<HomeState>(builder: (context, model, child) {
return buildTaskListView<Decrypt, Decrypt>(
model.decryptTasks,
model.decryptTasks
.where((task) => task.state == TaskState.finished)
.map((task) => task.info)
.toList(),
finishedTitle: 'Finished',
emptyView: const EmptyList(
hint: 'Requests for decryptions.',
),
unfinishedBuilder: (context, task) {
return SignTile(
name: task.info.name,
group: task.info.group.name,
desc: statusMessage(task),
trailing: TaskStateIndicator(task.state, task.round / task.nRounds),
initiallyExpanded: true,
showActions: task.approvable,
actions: [
FilledButton.tonal(
child: const Text('Decrypt'),
onPressed: () => model.joinDecrypt(task, agree: true),
),
OutlinedButton(
child: const Text('Decline'),
onPressed: () => model.joinDecrypt(task, agree: false),
)
],
);
},
finishedBuilder: (context, info) {
return SignTile(
name: info.name,
group: info.group.name,
trailing: const TaskStateIndicator(TaskState.finished, 1),
);
},
);
});
}
}

class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);

Expand All @@ -454,6 +502,7 @@ class HomePage extends StatelessWidget {
di.groupRepository,
di.fileRepository,
di.challengeRepository,
di.decryptRepository,
),
child: const HomePageView(),
);
Expand All @@ -470,15 +519,15 @@ class HomePageView extends StatefulWidget {
class _HomePageViewState extends State<HomePageView> {
int _index = 0;

Future<Group?> _selectGroup() async {
Future<Group?> _selectGroup(keyType) async {
final groups = context.read<HomeState>().groups;
return showDialog<Group?>(
context: context,
builder: (context) {
return SimpleDialog(
title: const Text('Select group'),
children: groups
.where((group) => group.keyType == KeyType.signPdf)
.where((group) => group.keyType == keyType)
.map((group) => SimpleDialogOption(
child: Text(group.name),
onPressed: () {
Expand All @@ -491,6 +540,51 @@ class _HomePageViewState extends State<HomePageView> {
);
}

Future<List<String>?> _inputMessage() async {
return showDialog<List<String>?>(
context: context,
builder: (context) {
var description = TextEditingController();
var message = TextEditingController();

return SimpleDialog(title: const Text('Input message'), children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: TextField(
controller: description,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Description',
),
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: TextField(
controller: message,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Message',
),
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child:
ElevatedButton(onPressed: () {
var result = List<String>.empty(growable: true);
result.add(description.text);
result.add(message.text);
Navigator.pop(context, result);
},
child: const Text("Next")
)
),
]);
},
);
}

static Future<FilePickerResult?> _pickPdfFile() async =>
FilePicker.platform.pickFiles(
type: FileType.custom,
Expand Down Expand Up @@ -532,7 +626,7 @@ class _HomePageViewState extends State<HomePageView> {
return;
}

final group = await _selectGroup();
final group = await _selectGroup(KeyType.signPdf);
if (group == null) return;

try {
Expand Down Expand Up @@ -562,11 +656,30 @@ class _HomePageViewState extends State<HomePageView> {
}
}

Future<void> _encrypt() async {
final message = await _inputMessage();
if (message == null) return;

final group = await _selectGroup(KeyType.decrypt); // TODO change
if (group == null) return;

try {
await context.read<HomeState>().decrypt(message[0], message[1], group);
} catch (e) {
showErrorDialog(
title: 'Decryption request failed',
desc: 'Please try again.',
);
rethrow;
}
}

@override
Widget build(BuildContext context) {
const pages = [
SigningSubPage(),
LogInSubPage(),
DecryptSubPage(),
GroupsSubPage(),
];

Expand All @@ -578,6 +691,12 @@ class _HomePageViewState extends State<HomePageView> {
icon: const Icon(Icons.add),
),
null,
FloatingActionButton.extended(
key: const ValueKey('EncryptFab'),
onPressed: _encrypt,
label: const Text('Encrypt'),
icon: const Icon(Icons.add),
),
FloatingActionButton.extended(
onPressed: _group,
label: const Text('New'),
Expand Down Expand Up @@ -654,6 +773,12 @@ class _HomePageViewState extends State<HomePageView> {
),
label: 'Log In',
),
NavigationDestination(
icon: CounterBadge(
stream: context.watch<HomeState>().nDecryptReqs,
child: const Icon(Icons.key),
),
label: 'Decrypt'),
NavigationDestination(
icon: CounterBadge(
stream: context.watch<HomeState>().nGroupReqs,
Expand Down
14 changes: 14 additions & 0 deletions lib/ui/home_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,32 @@ class HomeState with ChangeNotifier {

List<Group> groups = [];
List<File> files = [];
List<Decrypt> decrypts = [];

Device? device;

final GroupRepository _groupRepository;
final FileRepository _fileRepository;
final ChallengeRepository _challengeRepository;
final DecryptRepository _decryptRepository;

Stream<int> nGroupReqs = const Stream.empty();
Stream<int> nSignReqs = const Stream.empty();
Stream<int> nLoginReqs = const Stream.empty();
Stream<int> nDecryptReqs = const Stream.empty();

List<Task<Group>> groupTasks = [];
List<Task<File>> signTasks = [];
List<Task<Challenge>> loginTasks = [];
List<Task<Decrypt>> decryptTasks = [];

HomeState(
UserRepository userRepository,
DeviceRepository deviceRepository,
this._groupRepository,
this._fileRepository,
this._challengeRepository,
this._decryptRepository,
) {
userRepository.getUser().then((user) async {
if (user == null) return;
Expand Down Expand Up @@ -82,6 +87,10 @@ class HomeState with ChangeNotifier {
this.files = files;
notifyListeners();
});
_decryptRepository.observeDecrypts(did).listen((decrypts) {
this.decrypts = decrypts;
notifyListeners();
});
}

Future<void> addGroup(String name, List<Device> members, int threshold,
Expand All @@ -91,10 +100,15 @@ class HomeState with ChangeNotifier {
Future<void> sign(String path, Group group) =>
_fileRepository.sign(path, group.id);

Future<void> decrypt(String description, String message, Group group) =>
_decryptRepository.decrypt(description, message, group.id);

Future<void> joinGroup(Task<Group> task, {required bool agree}) =>
_groupRepository.approveTask(device!.id, task.id, agree: agree);
Future<void> joinSign(Task<File> task, {required bool agree}) =>
_fileRepository.approveTask(device!.id, task.id, agree: agree);
Future<void> joinLogin(Task<Challenge> task, {required bool agree}) =>
_challengeRepository.approveTask(device!.id, task.id, agree: agree);
Future<void> joinDecrypt(Task<Decrypt> task, {required bool agree}) =>
_challengeRepository.approveTask(device!.id, task.id, agree: agree);
}
8 changes: 6 additions & 2 deletions lib/ui/new_group_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ class _NewGroupPageState extends State<NewGroupPage> {
_nameController.text,
_members,
_threshold,
Protocol.gg18,
_keyType == KeyType.decrypt ? Protocol.elgamal : Protocol.gg18,
_keyType,
),
);
Expand Down Expand Up @@ -262,8 +262,12 @@ class _NewGroupPageState extends State<NewGroupPage> {
label: Text('Sign PDF'),
),
ButtonSegment<KeyType>(
value: KeyType.signDigest,
value: KeyType.signChallenge,
label: Text('Log In'),
),
ButtonSegment<KeyType>(
value: KeyType.decrypt,
label: Text('Decrypt'),
)
],
),
Expand Down
1 change: 1 addition & 0 deletions meesign_core/lib/meesign_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export 'src/data/task_repository.dart';
export 'src/data/group_repository.dart';
export 'src/data/file_repository.dart';
export 'src/data/challenge_repository.dart';
export 'src/data/decrypt_repository.dart';
export 'src/data/user_repository.dart';

export 'src/database/database.dart' show Database;
1 change: 1 addition & 0 deletions meesign_core/lib/meesign_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export 'src/model/task.dart';
export 'src/model/group.dart';
export 'src/model/file.dart';
export 'src/model/challenge.dart';
export 'src/model/decrypt.dart';
export 'src/model/protocol.dart' show Protocol;
export 'src/model/key_type.dart' show KeyType;
export 'src/model/user.dart';
Expand Down
2 changes: 1 addition & 1 deletion meesign_core/lib/src/data/challenge_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class ChallengeRepository extends TaskRepository<Challenge> {
final challenge = await _taskDao.getChallenge(did.bytes, task.id);
final group = await _taskDao.getGroup(did.bytes, gid: challenge.gid);
return task.copyWith(
context: ProtocolWrapper.sign(
context: ProtocolWrapper.init(
group.protocol.toNative(),
group.context,
),
Expand Down
Loading

0 comments on commit 293ef69

Please sign in to comment.