Encrypted messaging app
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 lines
3.6 KiB

  1. import 'dart:convert';
  2. import 'dart:typed_data';
  3. import "package:pointycastle/export.dart";
  4. import '../utils/encryption/aes_helper.dart';
  5. import '/utils/encryption/crypto_utils.dart';
  6. import '/utils/storage/database.dart';
  7. Friend findFriendByFriendId(List<Friend> friends, String id) {
  8. for (var friend in friends) {
  9. if (friend.friendId == id) {
  10. return friend;
  11. }
  12. }
  13. // Or return `null`.
  14. throw ArgumentError.value(id, "id", "No element with that id");
  15. }
  16. class Friend{
  17. String id;
  18. String userId;
  19. String username;
  20. String friendId;
  21. String friendSymmetricKey;
  22. RSAPublicKey publicKey;
  23. String acceptedAt;
  24. bool? selected;
  25. Friend({
  26. required this.id,
  27. required this.userId,
  28. required this.username,
  29. required this.friendId,
  30. required this.friendSymmetricKey,
  31. required this.publicKey,
  32. required this.acceptedAt,
  33. this.selected,
  34. });
  35. factory Friend.fromJson(Map<String, dynamic> json, RSAPrivateKey privKey) {
  36. Uint8List idDecrypted = CryptoUtils.rsaDecrypt(
  37. base64.decode(json['friend_id']),
  38. privKey,
  39. );
  40. Uint8List username = CryptoUtils.rsaDecrypt(
  41. base64.decode(json['friend_username']),
  42. privKey,
  43. );
  44. Uint8List symmetricKeyDecrypted = CryptoUtils.rsaDecrypt(
  45. base64.decode(json['symmetric_key']),
  46. privKey,
  47. );
  48. String publicKeyString = AesHelper.aesDecrypt(
  49. symmetricKeyDecrypted,
  50. base64.decode(json['asymmetric_public_key'])
  51. );
  52. RSAPublicKey publicKey = CryptoUtils.rsaPublicKeyFromPem(publicKeyString);
  53. return Friend(
  54. id: json['id'],
  55. userId: json['user_id'],
  56. username: String.fromCharCodes(username),
  57. friendId: String.fromCharCodes(idDecrypted),
  58. friendSymmetricKey: base64.encode(symmetricKeyDecrypted),
  59. publicKey: publicKey,
  60. acceptedAt: json['accepted_at'],
  61. );
  62. }
  63. @override
  64. String toString() {
  65. return '''
  66. id: $id
  67. userId: $userId
  68. username: $username
  69. friendId: $friendId
  70. accepted_at: $acceptedAt''';
  71. }
  72. Map<String, dynamic> toMap() {
  73. return {
  74. 'id': id,
  75. 'user_id': userId,
  76. 'username': username,
  77. 'friend_id': friendId,
  78. 'symmetric_key': friendSymmetricKey,
  79. 'asymmetric_public_key': publicKeyPem(),
  80. 'accepted_at': acceptedAt,
  81. };
  82. }
  83. String publicKeyPem() {
  84. return CryptoUtils.encodeRSAPublicKeyToPem(publicKey);
  85. }
  86. }
  87. // A method that retrieves all the dogs from the dogs table.
  88. Future<List<Friend>> getFriends() async {
  89. final db = await getDatabaseConnection();
  90. final List<Map<String, dynamic>> maps = await db.query('friends');
  91. return List.generate(maps.length, (i) {
  92. return Friend(
  93. id: maps[i]['id'],
  94. userId: maps[i]['user_id'],
  95. friendId: maps[i]['friend_id'],
  96. friendSymmetricKey: maps[i]['symmetric_key'],
  97. publicKey: CryptoUtils.rsaPublicKeyFromPem(maps[i]['asymmetric_public_key']),
  98. acceptedAt: maps[i]['accepted_at'],
  99. username: maps[i]['username'],
  100. );
  101. });
  102. }
  103. Future<Friend> getFriendByFriendId(String userId) async {
  104. final db = await getDatabaseConnection();
  105. final List<Map<String, dynamic>> maps = await db.query(
  106. 'friends',
  107. where: 'friend_id = ?',
  108. whereArgs: [userId],
  109. );
  110. if (maps.length != 1) {
  111. throw ArgumentError('Invalid user id');
  112. }
  113. return Friend(
  114. id: maps[0]['id'],
  115. userId: maps[0]['user_id'],
  116. friendId: maps[0]['friend_id'],
  117. friendSymmetricKey: maps[0]['symmetric_key'],
  118. publicKey: CryptoUtils.rsaPublicKeyFromPem(maps[0]['asymmetric_public_key']),
  119. acceptedAt: maps[0]['accepted_at'],
  120. username: maps[0]['username'],
  121. );
  122. }