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 // RiverpodGenerator
// ************************************************************************** // **************************************************************************
String _$localAccountsHash() => r'a4ad015e192c5db8e59ba2b5e922109c34572095'; String _$localAccountsHash() => r'27e90f03be60aa9f3d534456b5b697de669a20fe';
/// See also [LocalAccounts]. /// See also [LocalAccounts].
@ProviderFor(LocalAccounts) @ProviderFor(LocalAccounts)

View File

@ -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);

View File

@ -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;
} }
} }

View File

@ -2,11 +2,10 @@ 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,
{Object? Function(Object?)? toEncodable}) { {Object? Function(Object?)? toEncodable}) {

View File

@ -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: