readMessage1 method

Future<Uint8List> readMessage1(
  1. List<int> message
)

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');
  }
}