SMP handshake - validate key hash and protocol version
This commit is contained in:
parent
e8fe5632f4
commit
41681aaa6b
Binary file not shown.
@ -0,0 +1 @@
|
||||
void main() {}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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<int>;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
static void _checkVersion(SMPVersion version) {}
|
||||
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 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<Uint8List> _readEncrypted() async {
|
||||
final block = await _conn.read(blockSize);
|
||||
|
@ -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',
|
||||
|
Loading…
Reference in New Issue
Block a user