import 'dart:convert'; import 'dart:typed_data'; import 'package:pointycastle/export.dart'; import '/utils/encryption/aes_helper.dart'; import '/utils/encryption/crypto_utils.dart'; // TODO: Find good place for this to live Friend findFriendByFriendId(List friends, String id) { for (var friend in friends) { if (friend.friendId == id) { return friend; } } // Or return `null`. throw ArgumentError.value(id, 'id', 'No element with that id'); } class Friend { String id; String userId; String username; String friendId; String friendSymmetricKey; RSAPublicKey publicKey; DateTime? acceptedAt; bool? selected; Friend({ required this.id, required this.userId, required this.username, required this.friendId, required this.friendSymmetricKey, required this.publicKey, required this.acceptedAt, this.selected, }); factory Friend.fromJson(Map json, RSAPrivateKey privKey) { Uint8List idDecrypted = CryptoUtils.rsaDecrypt( base64.decode(json['friend_id']), privKey, ); Uint8List username = CryptoUtils.rsaDecrypt( base64.decode(json['friend_username']), privKey, ); Uint8List symmetricKeyDecrypted = CryptoUtils.rsaDecrypt( base64.decode(json['symmetric_key']), privKey, ); String publicKeyString = AesHelper.aesDecrypt( symmetricKeyDecrypted, base64.decode(json['asymmetric_public_key']) ); RSAPublicKey publicKey = CryptoUtils.rsaPublicKeyFromPem(publicKeyString); return Friend( id: json['id'], userId: json['user_id'], username: String.fromCharCodes(username), friendId: String.fromCharCodes(idDecrypted), friendSymmetricKey: base64.encode(symmetricKeyDecrypted), publicKey: publicKey, acceptedAt: json['accepted_at']['Valid'] ? DateTime.parse(json['accepted_at']['Time']) : null, ); } Map payloadJson() { Uint8List friendIdEncrypted = CryptoUtils.rsaEncrypt( Uint8List.fromList(friendId.codeUnits), publicKey, ); Uint8List usernameEncrypted = CryptoUtils.rsaEncrypt( Uint8List.fromList(username.codeUnits), publicKey, ); Uint8List symmetricKeyEncrypted = CryptoUtils.rsaEncrypt( Uint8List.fromList( base64.decode(friendSymmetricKey), ), publicKey, ); var publicKeyEncrypted = AesHelper.aesEncrypt( base64.decode(friendSymmetricKey), Uint8List.fromList(CryptoUtils.encodeRSAPublicKeyToPem(publicKey).codeUnits), ); return { 'id': id, 'user_id': userId, 'friend_id': base64.encode(friendIdEncrypted), 'friend_username': base64.encode(usernameEncrypted), 'symmetric_key': base64.encode(symmetricKeyEncrypted), 'asymmetric_public_key': publicKeyEncrypted, 'accepted_at': null, }; } String publicKeyPem() { return CryptoUtils.encodeRSAPublicKeyToPem(publicKey); } Map toMap() { return { 'id': id, 'user_id': userId, 'username': username, 'friend_id': friendId, 'symmetric_key': base64.encode(friendSymmetricKey.codeUnits), 'asymmetric_public_key': publicKeyPem(), 'accepted_at': acceptedAt?.toIso8601String(), }; } @override String toString() { return ''' id: $id userId: $userId username: $username friendId: $friendId accepted_at: $acceptedAt'''; } }