mirror of
https://gitlab.com/veilid/veilidchat.git
synced 2025-02-10 12:08:39 -05:00
encryption work
This commit is contained in:
parent
fe49beba9f
commit
9d8b609844
@ -6,7 +6,7 @@ part of 'local_accounts.dart';
|
|||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$localAccountsHash() => r'a4ad015e192c5db8e59ba2b5e922109c34572095';
|
String _$localAccountsHash() => r'27e90f03be60aa9f3d534456b5b697de669a20fe';
|
||||||
|
|
||||||
/// See also [LocalAccounts].
|
/// See also [LocalAccounts].
|
||||||
@ProviderFor(LocalAccounts)
|
@ProviderFor(LocalAccounts)
|
||||||
|
@ -13,7 +13,6 @@ class DHTRecord {
|
|||||||
static Future<DHTRecord> create(VeilidRoutingContext dhtctx,
|
static Future<DHTRecord> create(VeilidRoutingContext dhtctx,
|
||||||
{DHTSchema schema = const DHTSchema.dflt(oCnt: 1),
|
{DHTSchema schema = const DHTSchema.dflt(oCnt: 1),
|
||||||
int defaultSubkey = 0,
|
int defaultSubkey = 0,
|
||||||
KeyPair? writer,
|
|
||||||
DHTRecordEncryptionFactory crypto = DHTRecordEncryption.private}) async {
|
DHTRecordEncryptionFactory crypto = DHTRecordEncryption.private}) async {
|
||||||
DHTRecordDescriptor recordDescriptor = await dhtctx.createDHTRecord(schema);
|
DHTRecordDescriptor recordDescriptor = await dhtctx.createDHTRecord(schema);
|
||||||
|
|
||||||
@ -21,33 +20,55 @@ class DHTRecord {
|
|||||||
dhtctx: dhtctx,
|
dhtctx: dhtctx,
|
||||||
recordDescriptor: recordDescriptor,
|
recordDescriptor: recordDescriptor,
|
||||||
defaultSubkey: defaultSubkey,
|
defaultSubkey: defaultSubkey,
|
||||||
writer: writer);
|
writer: recordDescriptor.ownerKeyPair());
|
||||||
final encryption = crypto)
|
|
||||||
|
rec._encryption = crypto(rec);
|
||||||
|
|
||||||
|
return rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<DHTRecord> open(
|
static Future<DHTRecord> openRead(
|
||||||
VeilidRoutingContext dhtctx, TypedKey recordKey, KeyPair? writer,
|
VeilidRoutingContext dhtctx, TypedKey recordKey,
|
||||||
{int defaultSubkey = 0,
|
{int defaultSubkey = 0,
|
||||||
KeyPair? writer,
|
DHTRecordEncryptionFactory crypto = DHTRecordEncryption.private}) async {
|
||||||
DHTRecordEncryptionFactory encrypt = DHTRecordEncryption.private}) async {
|
|
||||||
DHTRecordDescriptor recordDescriptor =
|
DHTRecordDescriptor recordDescriptor =
|
||||||
await dhtctx.openDHTRecord(recordKey, writer);
|
await dhtctx.openDHTRecord(recordKey, null);
|
||||||
return DHTRecord(
|
final rec = DHTRecord(
|
||||||
dhtctx: dhtctx,
|
dhtctx: dhtctx,
|
||||||
recordDescriptor: recordDescriptor,
|
recordDescriptor: recordDescriptor,
|
||||||
defaultSubkey: defaultSubkey);
|
defaultSubkey: defaultSubkey,
|
||||||
|
writer: null);
|
||||||
|
|
||||||
|
rec._encryption = crypto(rec);
|
||||||
|
return rec;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<DHTRecord> openWrite(
|
||||||
|
VeilidRoutingContext dhtctx, TypedKey recordKey, KeyPair writer,
|
||||||
|
{int defaultSubkey = 0,
|
||||||
|
DHTRecordEncryptionFactory crypto = DHTRecordEncryption.private}) async {
|
||||||
|
DHTRecordDescriptor recordDescriptor =
|
||||||
|
await dhtctx.openDHTRecord(recordKey, writer);
|
||||||
|
final rec = DHTRecord(
|
||||||
|
dhtctx: dhtctx,
|
||||||
|
recordDescriptor: recordDescriptor,
|
||||||
|
defaultSubkey: defaultSubkey,
|
||||||
|
writer: writer);
|
||||||
|
rec._encryption = crypto(rec);
|
||||||
|
return rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
DHTRecord(
|
DHTRecord(
|
||||||
{required VeilidRoutingContext dhtctx,
|
{required VeilidRoutingContext dhtctx,
|
||||||
required DHTRecordDescriptor recordDescriptor,
|
required DHTRecordDescriptor recordDescriptor,
|
||||||
int defaultSubkey = 0, KeyPair? writer})
|
int defaultSubkey = 0,
|
||||||
|
KeyPair? writer})
|
||||||
: _dhtctx = dhtctx,
|
: _dhtctx = dhtctx,
|
||||||
_recordDescriptor = recordDescriptor,
|
_recordDescriptor = recordDescriptor,
|
||||||
_defaultSubkey = defaultSubkey,
|
_defaultSubkey = defaultSubkey,
|
||||||
_writer = writer;
|
_writer = writer;
|
||||||
|
|
||||||
int _subkey(int subkey) => (subkey == -1) ? _defaultSubkey : subkey;
|
int subkeyOrDefault(int subkey) => (subkey == -1) ? _defaultSubkey : subkey;
|
||||||
|
|
||||||
TypedKey key() {
|
TypedKey key() {
|
||||||
return _recordDescriptor.key;
|
return _recordDescriptor.key;
|
||||||
@ -58,11 +79,7 @@ class DHTRecord {
|
|||||||
}
|
}
|
||||||
|
|
||||||
KeyPair? ownerKeyPair() {
|
KeyPair? ownerKeyPair() {
|
||||||
final ownerSecret = _recordDescriptor.ownerSecret;
|
return _recordDescriptor.ownerKeyPair();
|
||||||
if (ownerSecret == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return KeyPair(key: _recordDescriptor.owner, secret: ownerSecret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyPair? writer() {
|
KeyPair? writer() {
|
||||||
@ -97,25 +114,27 @@ class DHTRecord {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<Uint8List?> get({int subkey = -1, bool forceRefresh = false}) async {
|
Future<Uint8List?> get({int subkey = -1, bool forceRefresh = false}) async {
|
||||||
ValueData? valueData = await _dhtctx.getDHTValue(
|
subkey = subkeyOrDefault(subkey);
|
||||||
_recordDescriptor.key, _subkey(subkey), false);
|
ValueData? valueData =
|
||||||
|
await _dhtctx.getDHTValue(_recordDescriptor.key, subkey, false);
|
||||||
if (valueData == null) {
|
if (valueData == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return valueData.data;
|
return _encryption.decrypt(valueData.data, subkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<T?> getJson<T>(T Function(Map<String, dynamic>) fromJson,
|
Future<T?> getJson<T>(T Function(Map<String, dynamic>) fromJson,
|
||||||
{int subkey = -1, bool forceRefresh = false}) async {
|
{int subkey = -1, bool forceRefresh = false}) async {
|
||||||
ValueData? valueData = await _dhtctx.getDHTValue(
|
final data = await get(subkey: subkey, forceRefresh: forceRefresh);
|
||||||
_recordDescriptor.key, _subkey(subkey), false);
|
if (data == null) {
|
||||||
if (valueData == null) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return valueData.readJsonData(fromJson);
|
return jsonDecodeBytes(fromJson, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> eventualWriteBytes(Uint8List newValue, {int subkey = -1}) async {
|
Future<void> eventualWriteBytes(Uint8List newValue, {int subkey = -1}) async {
|
||||||
|
subkey = subkeyOrDefault(subkey);
|
||||||
|
newValue = await _encryption.encrypt(newValue, subkey);
|
||||||
// Get existing identity key
|
// Get existing identity key
|
||||||
ValueData? valueData;
|
ValueData? valueData;
|
||||||
do {
|
do {
|
||||||
@ -125,8 +144,8 @@ class DHTRecord {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set the new data
|
// Set the new data
|
||||||
valueData = await _dhtctx.setDHTValue(
|
valueData =
|
||||||
_recordDescriptor.key, _subkey(subkey), newValue);
|
await _dhtctx.setDHTValue(_recordDescriptor.key, subkey, newValue);
|
||||||
|
|
||||||
// Repeat if newer data on the network was found
|
// Repeat if newer data on the network was found
|
||||||
} while (valueData != null);
|
} while (valueData != null);
|
||||||
@ -135,9 +154,10 @@ class DHTRecord {
|
|||||||
Future<void> eventualUpdateBytes(
|
Future<void> eventualUpdateBytes(
|
||||||
Future<Uint8List> Function(Uint8List oldValue) update,
|
Future<Uint8List> Function(Uint8List oldValue) update,
|
||||||
{int subkey = -1}) async {
|
{int subkey = -1}) async {
|
||||||
|
subkey = subkeyOrDefault(subkey);
|
||||||
// Get existing identity key
|
// Get existing identity key
|
||||||
ValueData? valueData = await _dhtctx.getDHTValue(
|
ValueData? valueData =
|
||||||
_recordDescriptor.key, _subkey(subkey), false);
|
await _dhtctx.getDHTValue(_recordDescriptor.key, subkey, false);
|
||||||
do {
|
do {
|
||||||
// Ensure it exists already
|
// Ensure it exists already
|
||||||
if (valueData == null) {
|
if (valueData == null) {
|
||||||
@ -145,11 +165,13 @@ class DHTRecord {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update the data
|
// Update the data
|
||||||
final newData = await update(valueData.data);
|
final oldData = await _encryption.decrypt(valueData.data, subkey);
|
||||||
|
final updatedData = await update(oldData);
|
||||||
|
final newData = await _encryption.encrypt(updatedData, subkey);
|
||||||
|
|
||||||
// Set it back
|
// Set it back
|
||||||
valueData = await _dhtctx.setDHTValue(
|
valueData =
|
||||||
_recordDescriptor.key, _subkey(subkey), newData);
|
await _dhtctx.setDHTValue(_recordDescriptor.key, subkey, newData);
|
||||||
|
|
||||||
// Repeat if newer data on the network was found
|
// Repeat if newer data on the network was found
|
||||||
} while (valueData != null);
|
} while (valueData != null);
|
||||||
|
@ -4,52 +4,50 @@ import 'package:veilid/veilid.dart';
|
|||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'tools.dart';
|
import 'tools.dart';
|
||||||
|
|
||||||
typedef DHTRecordEncryptionFactory = DHTRecordEncryption Function();
|
typedef DHTRecordEncryptionFactory = DHTRecordEncryption Function(DHTRecord);
|
||||||
|
|
||||||
abstract class DHTRecordEncryption {
|
abstract class DHTRecordEncryption {
|
||||||
factory DHTRecordEncryption.private() {
|
factory DHTRecordEncryption.private(DHTRecord record) {
|
||||||
return DHTRecordEncryptionPrivate();
|
return _DHTRecordEncryptionPrivate(record);
|
||||||
}
|
}
|
||||||
factory DHTRecordEncryption.public() {
|
factory DHTRecordEncryption.public(DHTRecord record) {
|
||||||
return DHTRecordEncryptionPublic();
|
return _DHTRecordEncryptionPublic(record);
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<Uint8List> encrypt(Uint8List data);
|
FutureOr<Uint8List> encrypt(Uint8List data, int subkey);
|
||||||
FutureOr<Uint8List> decrypt(Uint8List data);
|
FutureOr<Uint8List> decrypt(Uint8List data, int subkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////
|
////////////////////////////////////
|
||||||
/// Private DHT Record: Encrypted with the owner's secret key
|
/// Private DHT Record: Encrypted with the owner's secret key
|
||||||
class DHTRecordEncryptionPrivate implements DHTRecordEncryption {
|
class _DHTRecordEncryptionPrivate implements DHTRecordEncryption {
|
||||||
DHTRecordEncryptionPrivate() {
|
_DHTRecordEncryptionPrivate(DHTRecord record) {
|
||||||
//
|
// xxx derive key from record
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureOr<Uint8List> encrypt(Uint8List data) {
|
FutureOr<Uint8List> encrypt(Uint8List data, int subkey) {}
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureOr<Uint8List> decrypt(Uint8List data) {
|
FutureOr<Uint8List> decrypt(Uint8List data, int subkey) {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////
|
////////////////////////////////////
|
||||||
/// Public DHT Record: No encryption
|
/// Public DHT Record: No encryption
|
||||||
class DHTRecordEncryptionPublic implements DHTRecordEncryption {
|
class _DHTRecordEncryptionPublic implements DHTRecordEncryption {
|
||||||
DHTRecordEncryptionPublic() {
|
_DHTRecordEncryptionPublic(DHTRecord record) {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureOr<Uint8List> encrypt(Uint8List data) {
|
FutureOr<Uint8List> encrypt(Uint8List data, int subkey) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureOr<Uint8List> decrypt(Uint8List data) {
|
FutureOr<Uint8List> decrypt(Uint8List data, int subkey) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,9 @@ import 'package:veilid/veilid.dart';
|
|||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
extension FromValueDataJsonExt on ValueData {
|
T jsonDecodeBytes<T>(
|
||||||
T readJsonData<T>(T Function(Map<String, dynamic>) fromJson) {
|
T Function(Map<String, dynamic>) fromJson, Uint8List data) {
|
||||||
return fromJson(jsonDecode(utf8.decode(data)));
|
return fromJson(jsonDecode(utf8.decode(data)));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint8List jsonEncodeBytes(Object? object,
|
Uint8List jsonEncodeBytes(Object? object,
|
||||||
|
@ -904,7 +904,7 @@ packages:
|
|||||||
path: "../veilid/veilid-flutter"
|
path: "../veilid/veilid-flutter"
|
||||||
relative: true
|
relative: true
|
||||||
source: path
|
source: path
|
||||||
version: "0.1.1"
|
version: "0.1.4"
|
||||||
watcher:
|
watcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user