Skip to content
Snippets Groups Projects
Commit 60af2108 authored by Leon Tappe's avatar Leon Tappe :fire:
Browse files

add ticket encryption on local filesystem

parent bc0fad7d
No related branches found
No related tags found
No related merge requests found
......@@ -2,6 +2,8 @@ PODS:
- connectivity (0.0.1):
- Flutter
- Reachability
- device_info (0.0.1):
- Flutter
- DTTJailbreakDetection (0.4.0)
- Flutter (1.0.0)
- flutter_jailbreak_detection (1.0.0):
......@@ -12,6 +14,8 @@ PODS:
- Flutter
- path_provider_ios (0.0.1):
- Flutter
- platform_device_id (0.0.1):
- Flutter
- qr_code_scanner (0.2.0):
- Flutter
- MTBBarcodeScanner
......@@ -23,10 +27,12 @@ PODS:
DEPENDENCIES:
- connectivity (from `.symlinks/plugins/connectivity/ios`)
- device_info (from `.symlinks/plugins/device_info/ios`)
- Flutter (from `Flutter`)
- flutter_jailbreak_detection (from `.symlinks/plugins/flutter_jailbreak_detection/ios`)
- package_info (from `.symlinks/plugins/package_info/ios`)
- path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`)
- platform_device_id (from `.symlinks/plugins/platform_device_id/ios`)
- qr_code_scanner (from `.symlinks/plugins/qr_code_scanner/ios`)
- shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
......@@ -40,6 +46,8 @@ SPEC REPOS:
EXTERNAL SOURCES:
connectivity:
:path: ".symlinks/plugins/connectivity/ios"
device_info:
:path: ".symlinks/plugins/device_info/ios"
Flutter:
:path: Flutter
flutter_jailbreak_detection:
......@@ -48,6 +56,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/package_info/ios"
path_provider_ios:
:path: ".symlinks/plugins/path_provider_ios/ios"
platform_device_id:
:path: ".symlinks/plugins/platform_device_id/ios"
qr_code_scanner:
:path: ".symlinks/plugins/qr_code_scanner/ios"
shared_preferences_ios:
......@@ -57,12 +67,14 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
connectivity: c4130b2985d4ef6fd26f9702e886bd5260681467
device_info: d7d233b645a32c40dfdc212de5cf646ca482f175
DTTJailbreakDetection: 5e356c5badc17995f65a83ed9483f787a0057b71
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
flutter_jailbreak_detection: f6c01e4bc73641c6b69c5112e50301240601abb4
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
path_provider_ios: 7d7ce634493af4477d156294792024ec3485acd5
platform_device_id: 81b3e2993881f87d0c82ef151dc274df4869aef5
qr_code_scanner: bb67d64904c3b9658ada8c402e8b4d406d5d796e
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
shared_preferences_ios: aef470a42dc4675a1cdd50e3158b42e3d1232b32
......
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:bloc/bloc.dart';
import 'package:connectivity/connectivity.dart';
import 'package:crypto/crypto.dart';
import 'package:digital_3g_common/verification_api.dart';
import 'package:encrypt/encrypt.dart';
import 'package:flutter_jailbreak_detection/flutter_jailbreak_detection.dart';
import 'package:http/http.dart' as http;
import 'package:logging/logging.dart';
import 'package:path_provider/path_provider.dart';
import 'package:platform_device_id/platform_device_id.dart';
const String iv = 'c3eb69edb728ff3c';
enum EventType {
check,
......@@ -27,11 +33,14 @@ class VerificationBloc extends Bloc<VerificationEvent, VerificationState> {
VerificationResponse? _verification;
VerificationErrorType? _error;
Encrypter? _encrypter;
VerificationBloc(String url) : super(VerificationState.busy) {
_api = VerificationApi(http.Client(), url);
FlutterJailbreakDetection.jailbroken.then((bool jailbroken) {
if (!jailbroken) {
_initVerificationStore().then((_) => _initTicketFile().then((value) => _loadTicket()));
_initVerificationStore()
.then((_) => _initTicketFile().then((_) => _getDeviceId().then((_) => _loadTicket())));
} else {
_log.severe('jailbroken/rooted device detected, VerificationBloc halted');
_error = VerificationErrorType.root;
......@@ -116,7 +125,7 @@ class VerificationBloc extends Bloc<VerificationEvent, VerificationState> {
}
if (response.ticket != null && response.ticket!.isNotEmpty) {
_ticket = response.ticket;
await _ticketStore!.writeAsString(_ticket!, flush: true);
_writeEncryptedTicket(_ticket!);
yield VerificationState.unverified;
add(VerificationEvent.check());
}
......@@ -138,6 +147,13 @@ class VerificationBloc extends Bloc<VerificationEvent, VerificationState> {
void onRevoke() => add(VerificationEvent.revoke());
Future<void> _getDeviceId() async {
final deviceId = await PlatformDeviceId.getDeviceId;
final key = Key(sha256.convert(utf8.encode(deviceId!)).bytes as Uint8List);
_encrypter = Encrypter(AES(key, mode: AESMode.cbc));
}
Future<void> _initTicketFile() async {
_ticketStore = File('${(await getApplicationDocumentsDirectory()).path}/ticket');
_log.fine('initialized ticket store in ${_ticketStore?.path}');
......@@ -161,13 +177,24 @@ class VerificationBloc extends Bloc<VerificationEvent, VerificationState> {
ticket = await _ticketStore!.readAsString();
_log.finer('ticket: "$ticket"');
if (ticket.isNotEmpty) {
_ticket = ticket;
final iv = IV.fromBase64(ticket.substring(0, 24));
final encrypted = Encrypted.fromBase64(ticket.substring(24));
_ticket = _encrypter!.decrypt(encrypted, iv: iv);
add(VerificationEvent.check());
} else {
_log.fine('ticket empty, going to noTicket state');
add(VerificationEvent.revoke());
}
}
Future<void> _writeEncryptedTicket(String ticket) async {
final iv = IV.fromLength(16);
print(iv.base64.length); // 24
await _ticketStore!.writeAsString(
iv.base64 + _encrypter!.encrypt(_ticket!, iv: iv).base64,
flush: true,
);
}
}
class VerificationEvent {
......
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
args:
dependency: transitive
description:
name: args
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.0"
asn1lib:
dependency: transitive
description:
name: asn1lib
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
async:
dependency: transitive
description:
......@@ -78,6 +92,34 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
convert:
dependency: transitive
description:
name: convert
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
crypto:
dependency: "direct main"
description:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
device_info:
dependency: transitive
description:
name: device_info
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.3"
device_info_platform_interface:
dependency: transitive
description:
name: device_info_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
digital_3g_common:
dependency: "direct main"
description:
......@@ -85,6 +127,13 @@ packages:
relative: true
source: path
version: "0.5.0"
encrypt:
dependency: "direct main"
description:
name: encrypt
url: "https://pub.dartlang.org"
source: hosted
version: "5.0.1"
ffi:
dependency: transitive
description:
......@@ -263,6 +312,48 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.0"
platform_device_id:
dependency: "direct main"
description:
name: platform_device_id
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
platform_device_id_linux:
dependency: transitive
description:
name: platform_device_id_linux
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
platform_device_id_macos:
dependency: transitive
description:
name: platform_device_id_macos
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
platform_device_id_platform_interface:
dependency: transitive
description:
name: platform_device_id_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
platform_device_id_web:
dependency: transitive
description:
name: platform_device_id_web
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
platform_device_id_windows:
dependency: transitive
description:
name: platform_device_id_windows
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
plugin_platform_interface:
dependency: transitive
description:
......@@ -270,6 +361,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.2"
pointycastle:
dependency: transitive
description:
name: pointycastle
url: "https://pub.dartlang.org"
source: hosted
version: "3.5.0"
process:
dependency: transitive
description:
......
......@@ -21,6 +21,9 @@ dependencies:
shared_preferences: ^2.0.8
connectivity: ^3.0.6
flutter_jailbreak_detection: ^1.8.0
platform_device_id: ^1.0.1
encrypt: ^5.0.1
crypto: ^3.0.1
dev_dependencies:
flutter_lints: ^1.0.0
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment