mirror of
https://gitlab.com/veilid/veilid.git
synced 2025-08-01 19:26:03 -04:00
* API Breaking Change: CryptoSystem.verify() should return bool, and reserve errors for error cases, not validation failures.
* API Breaking Change: VeilidAPI.verify_signatures() returns Option<TypedKeySet> now Fixes #313
This commit is contained in:
parent
8e8ee06fe9
commit
05180252e4
36 changed files with 445 additions and 174 deletions
|
@ -30,6 +30,8 @@ void main() {
|
|||
test('get cryptosystem', testGetCryptoSystem);
|
||||
test('get cryptosystem invalid', testGetCryptoSystemInvalid);
|
||||
test('hash and verify password', testHashAndVerifyPassword);
|
||||
test('sign and verify signature', testSignAndVerifySignature);
|
||||
test('sign and verify signatures', testSignAndVerifySignatures);
|
||||
});
|
||||
|
||||
group('Table DB Tests', () {
|
||||
|
|
|
@ -32,6 +32,41 @@ Future<void> testHashAndVerifyPassword() async {
|
|||
expect(await cs.verifyPassword(utf8.encode('abc1235'), phash), isFalse);
|
||||
}
|
||||
|
||||
Future<void> testSignAndVerifySignature() async {
|
||||
final cs = await Veilid.instance.bestCryptoSystem();
|
||||
final kp1 = await cs.generateKeyPair();
|
||||
final kp2 = await cs.generateKeyPair();
|
||||
|
||||
// Signature match
|
||||
final sig = await cs.sign(kp1.key, kp1.secret, utf8.encode('abc123'));
|
||||
expect(await cs.verify(kp1.key, utf8.encode('abc123'), sig), isTrue);
|
||||
|
||||
// Signature mismatch
|
||||
final sig2 = await cs.sign(kp1.key, kp1.secret, utf8.encode('abc1234'));
|
||||
expect(await cs.verify(kp1.key, utf8.encode('abc1234'), sig2), isTrue);
|
||||
expect(await cs.verify(kp1.key, utf8.encode('abc12345'), sig2), isFalse);
|
||||
expect(await cs.verify(kp2.key, utf8.encode('abc1234'), sig2), isFalse);
|
||||
}
|
||||
|
||||
Future<void> testSignAndVerifySignatures() async {
|
||||
final cs = await Veilid.instance.bestCryptoSystem();
|
||||
final kind = cs.kind();
|
||||
final kp1 = await cs.generateKeyPair();
|
||||
|
||||
// Signature match
|
||||
final sigs = await Veilid.instance.generateSignatures(
|
||||
utf8.encode('abc123'), [TypedKeyPair.fromKeyPair(kind, kp1)]);
|
||||
expect(
|
||||
await Veilid.instance.verifySignatures(
|
||||
[TypedKey(kind: kind, value: kp1.key)], utf8.encode('abc123'), sigs),
|
||||
equals([TypedKey(kind: kind, value: kp1.key)]));
|
||||
// Signature mismatch
|
||||
expect(
|
||||
await Veilid.instance.verifySignatures(
|
||||
[TypedKey(kind: kind, value: kp1.key)], utf8.encode('abc1234'), sigs),
|
||||
isNull);
|
||||
}
|
||||
|
||||
Future<void> testGenerateSharedSecret() async {
|
||||
final cs = await Veilid.instance.bestCryptoSystem();
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ EXTERNAL SOURCES:
|
|||
SPEC CHECKSUMS:
|
||||
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
|
||||
macos_window_utils: 933f91f64805e2eb91a5bd057cf97cd097276663
|
||||
path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c
|
||||
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
|
||||
veilid: a54f57b7bcf0e4e072fe99272d76ca126b2026d0
|
||||
|
||||
PODFILE CHECKSUM: 73d2f470b1d889e27fcfda1d6e6efec66f98af3f
|
||||
|
|
|
@ -115,6 +115,13 @@ extension DHTRecordDescriptorExt on DHTRecordDescriptor {
|
|||
return KeyPair(key: owner, secret: ownerSecret!);
|
||||
}
|
||||
|
||||
TypedKey? ownerTypedSecret() {
|
||||
if (ownerSecret == null) {
|
||||
return null;
|
||||
}
|
||||
return TypedKey(kind: key.kind, value: ownerSecret!);
|
||||
}
|
||||
|
||||
TypedKeyPair? ownerTypedKeyPair() {
|
||||
if (ownerSecret == null) {
|
||||
return null;
|
||||
|
|
|
@ -44,6 +44,10 @@ Object? veilidApiToEncodable(Object? value) {
|
|||
List<T> Function(dynamic) jsonListConstructor<T>(
|
||||
T Function(dynamic) jsonConstructor) =>
|
||||
(dynamic j) => (j as List<dynamic>).map(jsonConstructor).toList();
|
||||
List<T>? Function(dynamic) optJsonListConstructor<T>(
|
||||
T Function(dynamic) jsonConstructor) =>
|
||||
(dynamic j) =>
|
||||
j == null ? null : (j as List<dynamic>).map(jsonConstructor).toList();
|
||||
|
||||
//////////////////////////////////////
|
||||
/// VeilidVersion
|
||||
|
@ -152,8 +156,8 @@ abstract class Veilid {
|
|||
List<CryptoKind> validCryptoKinds();
|
||||
Future<VeilidCryptoSystem> getCryptoSystem(CryptoKind kind);
|
||||
Future<VeilidCryptoSystem> bestCryptoSystem();
|
||||
Future<List<TypedKey>> verifySignatures(
|
||||
List<TypedKey> nodeIds, Uint8List data, List<TypedSignature> signatures);
|
||||
Future<List<TypedKey>?> verifySignatures(List<TypedKey> publicKeys,
|
||||
Uint8List data, List<TypedSignature> signatures);
|
||||
Future<List<TypedSignature>> generateSignatures(
|
||||
Uint8List data, List<TypedKeyPair> keyPairs);
|
||||
Future<TypedKeyPair> generateKeyPair(CryptoKind kind);
|
||||
|
|
|
@ -214,7 +214,7 @@ abstract class VeilidCryptoSystem {
|
|||
Future<Signature> signWithKeyPair(KeyPair keyPair, Uint8List data) =>
|
||||
sign(keyPair.key, keyPair.secret, data);
|
||||
|
||||
Future<void> verify(PublicKey key, Uint8List data, Signature signature);
|
||||
Future<bool> verify(PublicKey key, Uint8List data, Signature signature);
|
||||
Future<int> aeadOverhead();
|
||||
Future<Uint8List> decryptAead(Uint8List body, Nonce nonce,
|
||||
SharedSecret sharedSecret, Uint8List? associatedData);
|
||||
|
|
|
@ -1154,7 +1154,7 @@ class VeilidCryptoSystemFFI extends VeilidCryptoSystem {
|
|||
}
|
||||
|
||||
@override
|
||||
Future<void> verify(
|
||||
Future<bool> verify(
|
||||
PublicKey key, Uint8List data, Signature signature) async {
|
||||
final nativeKey = jsonEncode(key).toNativeUtf8();
|
||||
final nativeEncodedData = base64UrlNoPadEncode(data).toNativeUtf8();
|
||||
|
@ -1164,7 +1164,7 @@ class VeilidCryptoSystemFFI extends VeilidCryptoSystem {
|
|||
final sendPort = recvPort.sendPort;
|
||||
_ffi._cryptoVerify(sendPort.nativePort, _kind, nativeKey, nativeEncodedData,
|
||||
nativeSignature);
|
||||
return processFutureVoid(recvPort.first);
|
||||
return processFuturePlain(recvPort.first);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1742,7 +1742,7 @@ class VeilidFFI extends Veilid {
|
|||
VeilidCryptoSystemFFI._(this, _bestCryptoKind());
|
||||
|
||||
@override
|
||||
Future<List<TypedKey>> verifySignatures(List<TypedKey> nodeIds,
|
||||
Future<List<TypedKey>?> verifySignatures(List<TypedKey> nodeIds,
|
||||
Uint8List data, List<TypedSignature> signatures) async {
|
||||
final nativeNodeIds = jsonEncode(nodeIds).toNativeUtf8();
|
||||
final nativeData = base64UrlNoPadEncode(data).toNativeUtf8();
|
||||
|
@ -1752,7 +1752,7 @@ class VeilidFFI extends Veilid {
|
|||
final sendPort = recvPort.sendPort;
|
||||
_verifySignatures(
|
||||
sendPort.nativePort, nativeNodeIds, nativeData, nativeSignatures);
|
||||
return processFutureJson(
|
||||
return processFutureOptJson(
|
||||
jsonListConstructor<TypedKey>(TypedKey.fromJson), recvPort.first);
|
||||
}
|
||||
|
||||
|
|
|
@ -359,7 +359,7 @@ class VeilidCryptoSystemJS extends VeilidCryptoSystem {
|
|||
]))));
|
||||
|
||||
@override
|
||||
Future<void> verify(PublicKey key, Uint8List data, Signature signature) =>
|
||||
Future<bool> verify(PublicKey key, Uint8List data, Signature signature) =>
|
||||
_wrapApiPromise(js_util.callMethod(wasm, 'crypto_verify', [
|
||||
_kind,
|
||||
jsonEncode(key),
|
||||
|
@ -655,10 +655,10 @@ class VeilidJS extends Veilid {
|
|||
this, js_util.callMethod(wasm, 'best_crypto_kind', []));
|
||||
|
||||
@override
|
||||
Future<List<TypedKey>> verifySignatures(List<TypedKey> nodeIds,
|
||||
Future<List<TypedKey>?> verifySignatures(List<TypedKey> nodeIds,
|
||||
Uint8List data, List<TypedSignature> signatures) async =>
|
||||
jsonListConstructor(TypedKey.fromJson)(jsonDecode(await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, 'verify_signatures', [
|
||||
optJsonListConstructor(TypedKey.fromJson)(jsonDecode(
|
||||
await _wrapApiPromise(js_util.callMethod(wasm, 'verify_signatures', [
|
||||
jsonEncode(nodeIds),
|
||||
base64UrlNoPadEncode(data),
|
||||
jsonEncode(signatures)
|
||||
|
|
|
@ -1525,8 +1525,8 @@ pub extern "C" fn crypto_verify(
|
|||
let csv = crypto.get(kind).ok_or_else(|| {
|
||||
veilid_core::VeilidAPIError::invalid_argument("crypto_verify", "kind", kind.to_string())
|
||||
})?;
|
||||
csv.verify(&key, &data, &signature)?;
|
||||
APIRESULT_VOID
|
||||
let out = csv.verify(&key, &data, &signature)?;
|
||||
APIResult::Ok(out)
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue