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.

140 lines
3.5 KiB

import 'dart:convert';
import 'dart:typed_data';
import 'package:pointycastle/export.dart';
import '/utils/encryption/aes_helper.dart';
import '/utils/encryption/crypto_utils.dart';
import '/utils/storage/database.dart';
// TODO: Find good place for this to live
Friend findFriendByFriendId(List<Friend> 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<String, dynamic> 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<String, dynamic> 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<String, dynamic> 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''';
}
}