readMessage1 method
Processes message 1 and returns its payload, the session token.
Throws NoiseException with NoiseError.messageTooLong or NoiseError.handshakeFailed (wrong prologue, wrong static key, tampered or short message, low-order key); both break the responder.
Implementation
Future<Uint8List> readMessage1(List<int> message) async {
_guard('read message 1', 0);
_step = -1;
if (message.length > maxNoiseMessageLength) {
_broken = true;
throw NoiseException(
NoiseError.messageTooLong,
'read message 1',
'${message.length} bytes, limit $maxNoiseMessageLength',
);
}
if (!isByteList(message)) {
_broken = true;
throw const NoiseException(
NoiseError.handshakeFailed,
'read message 1',
'value outside a byte',
);
}
if (message.length < _handshakeOverhead) {
_broken = true;
throw NoiseException(
NoiseError.handshakeFailed,
'read message 1',
'${message.length} bytes, minimum $_handshakeOverhead',
);
}
try {
final re = Uint8List.fromList(message.sublist(0, keyLength));
await _ss.mixHash(re);
await _ss.mixKey(await _dh(_static, re, 'read message 1'));
final payload = await _ss.decryptAndHash(message.sublist(keyLength));
_initiatorEphemeral = re;
_step = 1;
return payload;
} on AuthenticationFailure {
_broken = true;
throw NoiseException(
NoiseError.handshakeFailed,
'read message 1',
'${message.length} bytes',
);
} on NoiseException {
_broken = true;
rethrow;
} on Object {
// Any other failure of a step ends the handshake as well (D-M2-38-8).
_broken = true;
throw const NoiseException(NoiseError.handshakeFailed, 'handshake step');
}
}