diff --git a/packages/simplex_app/build/test_cache/build/c075001b96339384a97db4862b8ab8db.cache.dill.track.dill b/packages/simplex_app/build/test_cache/build/c075001b96339384a97db4862b8ab8db.cache.dill.track.dill index b372cb889..f807159b2 100644 Binary files a/packages/simplex_app/build/test_cache/build/c075001b96339384a97db4862b8ab8db.cache.dill.track.dill and b/packages/simplex_app/build/test_cache/build/c075001b96339384a97db4862b8ab8db.cache.dill.track.dill differ diff --git a/packages/simplexmq/example/simplexmq_example.dart b/packages/simplexmq/example/simplexmq_example.dart index e69de29bb..ab73b3a23 100644 --- a/packages/simplexmq/example/simplexmq_example.dart +++ b/packages/simplexmq/example/simplexmq_example.dart @@ -0,0 +1 @@ +void main() {} diff --git a/packages/simplexmq/lib/src/buffer.dart b/packages/simplexmq/lib/src/buffer.dart index 4f5cbe13b..a9fdf934c 100644 --- a/packages/simplexmq/lib/src/buffer.dart +++ b/packages/simplexmq/lib/src/buffer.dart @@ -142,3 +142,13 @@ Uint8List encodeInt16(int n) { ByteData.sublistView(data).setInt16(0, n); return data; } + +extension EqualUint8List on Uint8List { + bool equal(Uint8List b) { + if (length != b.length) return false; + for (int i = 0; i < length; i++) { + if (this[i] != b[i]) return false; + } + return true; + } +} diff --git a/packages/simplexmq/lib/src/parser.dart b/packages/simplexmq/lib/src/parser.dart index 0dc46f43c..18374e182 100644 --- a/packages/simplexmq/lib/src/parser.dart +++ b/packages/simplexmq/lib/src/parser.dart @@ -13,6 +13,7 @@ final charUpperA = cc('A'); final charUpperZ = cc('Z'); final charPlus = cc('+'); final charSlash = cc('/'); +final charDot = cc('.'); class Parser { final Uint8List _s; @@ -70,6 +71,14 @@ class Parser { return true; }); + // takes the passed char + bool? char(int c) => _run(() { + if (_s[_pos] == c) { + _pos++; + return true; + } + }); + // takes space bool? space() => _run(() { if (_s[_pos] == charSpace) { diff --git a/packages/simplexmq/lib/src/transport.dart b/packages/simplexmq/lib/src/transport.dart index 031c77672..87240ad20 100644 --- a/packages/simplexmq/lib/src/transport.dart +++ b/packages/simplexmq/lib/src/transport.dart @@ -1,8 +1,10 @@ import 'dart:async'; import 'dart:typed_data'; import 'package:pointycastle/asymmetric/api.dart'; +import 'package:pointycastle/digests/sha256.dart'; import 'buffer.dart'; import 'crypto.dart'; +import 'parser.dart'; import 'rsa_keys.dart'; abstract class Transport { @@ -51,7 +53,7 @@ class ServerHandshake { typedef SMPVersion = List; -// SMPVersion _currentSMPVersion = const [0, 4, 1, 0]; +SMPVersion _currentSMPVersion = const [0, 4, 1, 0]; const int _serverHeaderSize = 8; const int _binaryRsaTransport = 0; const int _transportBlockSize = 4096; @@ -96,7 +98,8 @@ class SMPTransportClient { } static void validateKeyHash_2(Uint8List rawKey, Uint8List keyHash) { - // todo + if (keyHash.equal(SHA256Digest().process(rawKey))) return; + throw Exception('smp handshake error: bad key hash'); } static ServerHeader parseServerHeader(Uint8List a) { @@ -129,10 +132,33 @@ class SMPTransportClient { _parseSMPVersion(await _readEncrypted()); static SMPVersion _parseSMPVersion(Uint8List block) { - return []; + final p = Parser(block); + final SMPVersion version = [0, 0, 0, 0]; + void setVer(int i, int? v) { + if (v == null || p.fail) { + throw Exception('smp handshake error: bad version format'); + } + version[i] = v; + } + + for (var i = 0; i < 3; i++) { + final v = p.decimal(); + p.char(charDot); + setVer(i, v); + } + final v = p.decimal(); + p.space(); + setVer(3, v); + return version; } - static void _checkVersion(SMPVersion version) {} + static void _checkVersion(SMPVersion srvVersion) { + final s0 = srvVersion[0]; + final c0 = _currentSMPVersion[0]; + if (s0 > c0 || (s0 == c0 && srvVersion[1] > _currentSMPVersion[1])) { + throw Exception('smp handshake error: incompatible server version'); + } + } Future _readEncrypted() async { final block = await _conn.read(blockSize); diff --git a/packages/simplexmq_io/test/transport_test.dart b/packages/simplexmq_io/test/transport_test.dart index 11a68b89b..a9ba0db78 100644 --- a/packages/simplexmq_io/test/transport_test.dart +++ b/packages/simplexmq_io/test/transport_test.dart @@ -1,5 +1,6 @@ // import 'dart:io'; import 'package:simplexmq/simplexmq.dart'; +import 'package:simplexmq/src/buffer.dart'; import 'package:simplexmq_io/simplexmq_io.dart'; import 'package:test/test.dart'; @@ -9,7 +10,9 @@ void main() { 'establish connection (expects SMP server on localhost:5223)', () async { final conn = await SocketTransport.connect('localhost', 5223); - final smp = await SMPTransportClient.connect(conn); + final smp = await SMPTransportClient.connect(conn, + keyHash: decode64( + encodeAscii('pH7bg7B6vB3uJ1poKmClTAqr7yYWnAtapnIDN7ypKxU='))); expect(smp is SMPTransportClient, true); }, skip: 'requires SMP server on port 5223',