challenge method

  1. @override
Future<Authenticate> challenge(
  1. Extra extra
)
override

Called when the router sends a challenge (CHALLENGE frame).

Implementation

@override
Future<Authenticate> challenge(Extra extra) async {
  await AbstractAuthentication.streamAddAwaited<Extra>(
    _challengeStreamController,
    extra,
  );

  final authenticate = Authenticate();
  if (extra.challenge == null) {
    final error = Error(
      MessageTypes.codeChallenge,
      -1,
      HashMap<String, Object>(),
      Error.authorizationFailed,
    );
    error.details['reason'] =
        'No challenge or secret given, wrong router response';
    return Future.error(error);
  }

  Uint8List key;
  if (extra.salt == null) {
    key = Uint8List.fromList(
      encodeString(secret, stringEncoding: stringEncoding),
    );
  } else {
    key = deriveKey(
      secret,
      encodeString(extra.salt!, stringEncoding: stringEncoding),
      iterations: extra.iterations == null || extra.iterations! <= 0
          ? defaultIterations
          : extra.iterations!,
      keylen: extra.keyLen == null || extra.keyLen! <= 0
          ? defaultKeyLength
          : extra.keyLen!,
      stringEncoding: stringEncoding,
    );
  }

  authenticate.signature = encodeHmac(
    Uint8List.fromList(base64.encode(key).codeUnits),
    extra.keyLen == null || extra.keyLen! <= 0
        ? defaultKeyLength
        : extra.keyLen!,
    Uint8List.fromList(
      encodeString(extra.challenge!, stringEncoding: stringEncoding),
    ),
  );
  return authenticate;
}