refactor: Json signature check

This commit is contained in:
Christian Pauly 2020-09-16 10:39:04 +02:00
parent df2cfb3faf
commit 0871e218d1
3 changed files with 37 additions and 9 deletions

View file

@ -24,6 +24,7 @@ import 'package:famedlysdk/matrix_api.dart';
import 'package:olm/olm.dart' as olm;
import 'package:pedantic/pedantic.dart';
import '../encryption/utils/json_signature_check_extension.dart';
import '../src/utils/logs.dart';
import 'encryption.dart';
import 'utils/olm_session.dart';
@ -75,7 +76,8 @@ class OlmManager {
}
}
/// Adds a signature to this json from this olm account.
/// Adds a signature to this json from this olm account and returns the signed
/// json.
Map<String, dynamic> signJson(Map<String, dynamic> payload) {
if (!enabled) throw ('Encryption is disabled');
final Map<String, dynamic> unsigned = payload['unsigned'];
@ -105,6 +107,7 @@ class OlmManager {
}
/// Checks the signature of a signed json object.
@deprecated
bool checkJsonSignature(String key, Map<String, dynamic> signedJson,
String userId, String deviceId) {
if (!enabled) throw ('Encryption is disabled');
@ -406,8 +409,7 @@ class OlmManager {
final identityKey =
client.userDeviceKeys[userId].deviceKeys[deviceId].curve25519Key;
for (Map<String, dynamic> deviceKey in deviceKeysEntry.value.values) {
if (!checkJsonSignature(
fingerprintKey, deviceKey, userId, deviceId)) {
if (!deviceKey.checkJsonSignature(fingerprintKey, userId, deviceId)) {
continue;
}
var session = olm.Session();

View file

@ -0,0 +1,29 @@
import 'package:canonical_json/canonical_json.dart';
import 'package:famedlysdk/src/utils/logs.dart';
import 'package:olm/olm.dart' as olm;
extension JsonSignatureCheckExtension on Map<String, dynamic> {
/// Checks the signature of a signed json object.
bool checkJsonSignature(String key, String userId, String deviceId) {
final Map<String, dynamic> signatures = this['signatures'];
if (signatures == null || !signatures.containsKey(userId)) return false;
remove('unsigned');
remove('signatures');
if (!signatures[userId].containsKey('ed25519:$deviceId')) return false;
final String signature = signatures[userId]['ed25519:$deviceId'];
final canonical = canonicalJson.encode(this);
final message = String.fromCharCodes(canonical);
var isValid = false;
final olmutil = olm.Utility();
try {
olmutil.ed25519_verify(key, message, signature);
isValid = true;
} catch (e, s) {
isValid = false;
Logs.error('[LibOlm] Signature check failed: ' + e.toString(), s);
} finally {
olmutil.free();
}
return isValid;
}
}

View file

@ -21,6 +21,7 @@ import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/src/utils/logs.dart';
import 'package:test/test.dart';
import 'package:olm/olm.dart' as olm;
import 'package:famedlysdk/encryption/utils/json_signature_check_extension.dart';
import '../fake_client.dart';
import '../fake_matrix_api.dart';
@ -51,13 +52,9 @@ void main() {
};
final signedPayload = client.encryption.olmManager.signJson(payload);
expect(
client.encryption.olmManager.checkJsonSignature(client.fingerprintKey,
signedPayload, client.userID, client.deviceID),
signedPayload.checkJsonSignature(
client.fingerprintKey, client.userID, client.deviceID),
true);
expect(
client.encryption.olmManager.checkJsonSignature(
client.fingerprintKey, payload, client.userID, client.deviceID),
false);
});
test('uploadKeys', () async {