From 41681aaa6bfefcd33afcf916df26c64b1d37f16f Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com> Date: Tue, 26 Oct 2021 21:38:15 +0100 Subject: [PATCH] SMP handshake - validate key hash and protocol version --- ...9384a97db4862b8ab8db.cache.dill.track.dill | Bin 31442464 -> 31442464 bytes .../simplexmq/example/simplexmq_example.dart | 1 + packages/simplexmq/lib/src/buffer.dart | 10 ++++++ packages/simplexmq/lib/src/parser.dart | 9 +++++ packages/simplexmq/lib/src/transport.dart | 34 +++++++++++++++--- .../simplexmq_io/test/transport_test.dart | 5 ++- 6 files changed, 54 insertions(+), 5 deletions(-) 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 b372cb889982e3a6ad836f5b4a352c93d217d28c..f807159b200c308c2a7ff86e1293dfaccd6224f7 100644 GIT binary patch delta 1449 zcma*fcbv}!9LMp;o3dR98Idvzch24&;p~u2&bTvj*48huHmAN?7?Kn9USG9d=@Izt%BForXNk-WhuMl*&t8A}Q< zj`6(31ST?xw=t8M!c?X)of*tz7PFbdT;?&KcX*ctEMyUjNo5I3S;lf!u##1*W({ju z$9t@20~^`IX11`EZER-;JK4o<_OO?Iyw85Z9N-{_ILr}_@&O-mjN_c(B&Rsd8P0N! z^IYH}m-vXwT;VF$xXul3a*Nxf@iCw9DWCBrIZ znP2#o-}s$B_>;f*n}2vXL6)3OPA@+uKQ3pGGs>Cd%yJevtDH^FE=R~u$T{SkaxVEv zIk%ig&MQA9=acix1>}PA({drXu>6c%M1EF&PA)1JlZ(qGqE59Vylk3Y3RL zH<6pl&E)3t%W@03rQAw>MQ$y(k=x4c!{rh3NcjzUlssA|?uW zUM#1|OXQ{UGI_bYLS8Aal2^-XS=G0Zj@RSW{s+_s#BfJdX*_o!286RmH9Zu8z4F3W& CdQ9B_ delta 1449 zcma*fRg~5R7{uW-bW0-*(jiMXNXgQTgfuL<)barmQv0Ka?q0f)Zun>YjOMhUC9P=9TeP7q?P$;2bf6=h=u8*7(v9x) zAc~&!qBni$OFyFN&j1E8h{41#gb+g+#&F(Y1S1*6Xx?QEV;RSICJ+luWD=8^!c?X) z9W#TO%wjfkn9Drovw(#xVlhit$}*O-f|aZyj@7JTE$dj%1~#&Z&1_*S+t|(y-eV`b z*v%gHvXA{7;2?)M%n^=qjN^nk!AVYWnlqf`9OrqT3tZ$9m-&DXxx!Vhah)67E#S^Mmdw5S-TvM(k*Ou$ZZ_0J$NV%R|Uv3~blpD#7h-GF-m_X9o(_&DG}z(a+n_m9{2CBw0irxJxQok;a+RvbtGkt zQ2CmDTZbZgMh^{zqGCFSqK1SzNB0>LiW(3VQ=(F _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',