encryption work

This commit is contained in:
Christien Rioux 2023-07-20 23:35:02 -04:00
parent fe49beba9f
commit 9d8b609844
5 changed files with 74 additions and 55 deletions

View File

@ -6,7 +6,7 @@ part of 'local_accounts.dart';
// RiverpodGenerator
// **************************************************************************
String _$localAccountsHash() => r'a4ad015e192c5db8e59ba2b5e922109c34572095';
String _$localAccountsHash() => r'27e90f03be60aa9f3d534456b5b697de669a20fe';
/// See also [LocalAccounts].
@ProviderFor(LocalAccounts)

View File

@ -13,7 +13,6 @@ class DHTRecord {
static Future<DHTRecord> create(VeilidRoutingContext dhtctx,
{DHTSchema schema = const DHTSchema.dflt(oCnt: 1),
int defaultSubkey = 0,
KeyPair? writer,
DHTRecordEncryptionFactory crypto = DHTRecordEncryption.private}) async {
DHTRecordDescriptor recordDescriptor = await dhtctx.createDHTRecord(schema);
@ -21,33 +20,55 @@ class DHTRecord {
dhtctx: dhtctx,
recordDescriptor: recordDescriptor,
defaultSubkey: defaultSubkey,
writer: writer);
final encryption = crypto)
writer: recordDescriptor.ownerKeyPair());
rec._encryption = crypto(rec);
return rec;
}
static Future<DHTRecord> open(
VeilidRoutingContext dhtctx, TypedKey recordKey, KeyPair? writer,
static Future<DHTRecord> openRead(
VeilidRoutingContext dhtctx, TypedKey recordKey,
{int defaultSubkey = 0,
KeyPair? writer,
DHTRecordEncryptionFactory encrypt = DHTRecordEncryption.private}) async {
DHTRecordEncryptionFactory crypto = DHTRecordEncryption.private}) async {
DHTRecordDescriptor recordDescriptor =
await dhtctx.openDHTRecord(recordKey, writer);
return DHTRecord(
await dhtctx.openDHTRecord(recordKey, null);
final rec = DHTRecord(
dhtctx: dhtctx,
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(
{required VeilidRoutingContext dhtctx,
required DHTRecordDescriptor recordDescriptor,
int defaultSubkey = 0, KeyPair? writer})
int defaultSubkey = 0,
KeyPair? writer})
: _dhtctx = dhtctx,
_recordDescriptor = recordDescriptor,
_defaultSubkey = defaultSubkey,
_writer = writer;
int _subkey(int subkey) => (subkey == -1) ? _defaultSubkey : subkey;
int subkeyOrDefault(int subkey) => (subkey == -1) ? _defaultSubkey : subkey;
TypedKey key() {
return _recordDescriptor.key;
@ -58,11 +79,7 @@ class DHTRecord {
}
KeyPair? ownerKeyPair() {
final ownerSecret = _recordDescriptor.ownerSecret;
if (ownerSecret == null) {
return null;
}
return KeyPair(key: _recordDescriptor.owner, secret: ownerSecret);
return _recordDescriptor.ownerKeyPair();
}
KeyPair? writer() {
@ -97,25 +114,27 @@ class DHTRecord {
}
Future<Uint8List?> get({int subkey = -1, bool forceRefresh = false}) async {
ValueData? valueData = await _dhtctx.getDHTValue(
_recordDescriptor.key, _subkey(subkey), false);
subkey = subkeyOrDefault(subkey);
ValueData? valueData =
await _dhtctx.getDHTValue(_recordDescriptor.key, subkey, false);
if (valueData == null) {
return null;
}
return valueData.data;
return _encryption.decrypt(valueData.data, subkey);
}
Future<T?> getJson<T>(T Function(Map<String, dynamic>) fromJson,
{int subkey = -1, bool forceRefresh = false}) async {
ValueData? valueData = await _dhtctx.getDHTValue(
_recordDescriptor.key, _subkey(subkey), false);
if (valueData == null) {
final data = await get(subkey: subkey, forceRefresh: forceRefresh);
if (data == null) {
return null;
}
return valueData.readJsonData(fromJson);
return jsonDecodeBytes(fromJson, data);
}
Future<void> eventualWriteBytes(Uint8List newValue, {int subkey = -1}) async {
subkey = subkeyOrDefault(subkey);
newValue = await _encryption.encrypt(newValue, subkey);
// Get existing identity key
ValueData? valueData;
do {
@ -125,8 +144,8 @@ class DHTRecord {
}
// Set the new data
valueData = await _dhtctx.setDHTValue(
_recordDescriptor.key, _subkey(subkey), newValue);
valueData =
await _dhtctx.setDHTValue(_recordDescriptor.key, subkey, newValue);
// Repeat if newer data on the network was found
} while (valueData != null);
@ -135,9 +154,10 @@ class DHTRecord {
Future<void> eventualUpdateBytes(
Future<Uint8List> Function(Uint8List oldValue) update,
{int subkey = -1}) async {
subkey = subkeyOrDefault(subkey);
// Get existing identity key
ValueData? valueData = await _dhtctx.getDHTValue(
_recordDescriptor.key, _subkey(subkey), false);
ValueData? valueData =
await _dhtctx.getDHTValue(_recordDescriptor.key, subkey, false);
do {
// Ensure it exists already
if (valueData == null) {
@ -145,11 +165,13 @@ class DHTRecord {
}
// 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
valueData = await _dhtctx.setDHTValue(
_recordDescriptor.key, _subkey(subkey), newData);
valueData =
await _dhtctx.setDHTValue(_recordDescriptor.key, subkey, newData);
// Repeat if newer data on the network was found
} while (valueData != null);

View File

@ -4,52 +4,50 @@ import 'package:veilid/veilid.dart';
import 'dart:typed_data';
import 'tools.dart';
typedef DHTRecordEncryptionFactory = DHTRecordEncryption Function();
typedef DHTRecordEncryptionFactory = DHTRecordEncryption Function(DHTRecord);
abstract class DHTRecordEncryption {
factory DHTRecordEncryption.private() {
return DHTRecordEncryptionPrivate();
factory DHTRecordEncryption.private(DHTRecord record) {
return _DHTRecordEncryptionPrivate(record);
}
factory DHTRecordEncryption.public() {
return DHTRecordEncryptionPublic();
factory DHTRecordEncryption.public(DHTRecord record) {
return _DHTRecordEncryptionPublic(record);
}
FutureOr<Uint8List> encrypt(Uint8List data);
FutureOr<Uint8List> decrypt(Uint8List data);
FutureOr<Uint8List> encrypt(Uint8List data, int subkey);
FutureOr<Uint8List> decrypt(Uint8List data, int subkey);
}
////////////////////////////////////
/// Private DHT Record: Encrypted with the owner's secret key
class DHTRecordEncryptionPrivate implements DHTRecordEncryption {
DHTRecordEncryptionPrivate() {
//
class _DHTRecordEncryptionPrivate implements DHTRecordEncryption {
_DHTRecordEncryptionPrivate(DHTRecord record) {
// xxx derive key from record
}
@override
FutureOr<Uint8List> encrypt(Uint8List data) {
//
}
FutureOr<Uint8List> encrypt(Uint8List data, int subkey) {}
@override
FutureOr<Uint8List> decrypt(Uint8List data) {
FutureOr<Uint8List> decrypt(Uint8List data, int subkey) {
//
}
}
////////////////////////////////////
/// Public DHT Record: No encryption
class DHTRecordEncryptionPublic implements DHTRecordEncryption {
DHTRecordEncryptionPublic() {
class _DHTRecordEncryptionPublic implements DHTRecordEncryption {
_DHTRecordEncryptionPublic(DHTRecord record) {
//
}
@override
FutureOr<Uint8List> encrypt(Uint8List data) {
FutureOr<Uint8List> encrypt(Uint8List data, int subkey) {
return data;
}
@override
FutureOr<Uint8List> decrypt(Uint8List data) {
FutureOr<Uint8List> decrypt(Uint8List data, int subkey) {
return data;
}
}

View File

@ -2,10 +2,9 @@ import 'package:veilid/veilid.dart';
import 'dart:typed_data';
import 'dart:convert';
extension FromValueDataJsonExt on ValueData {
T readJsonData<T>(T Function(Map<String, dynamic>) fromJson) {
return fromJson(jsonDecode(utf8.decode(data)));
}
T jsonDecodeBytes<T>(
T Function(Map<String, dynamic>) fromJson, Uint8List data) {
return fromJson(jsonDecode(utf8.decode(data)));
}
Uint8List jsonEncodeBytes(Object? object,

View File

@ -904,7 +904,7 @@ packages:
path: "../veilid/veilid-flutter"
relative: true
source: path
version: "0.1.1"
version: "0.1.4"
watcher:
dependency: transitive
description: