KeyFileCredentials constructor

KeyFileCredentials(
  1. Uint8List keyFileContents
)

Implementation

factory KeyFileCredentials(Uint8List keyFileContents) {
  try {
    final keyFileAsString = utf8.decode(keyFileContents);
    if (_hexValuePattern.hasMatch(keyFileAsString)) {
      return KeyFileCredentials._(ProtectedValue.fromBinary(
          convert.hex.decode(keyFileAsString) as Uint8List));
    }
    final xmlContent = xml.XmlDocument.parse(keyFileAsString);
    final metaVersion =
        xmlContent.findAllElements(_nodeVersion).singleOrNull?.text;
    final key = xmlContent.findAllElements(_nodeKey).single;
    final dataString = key.findElements(_nodeData).single;
    final encoded = dataString.text.replaceAll(RegExp(r'\s'), '');
    Uint8List dataBytes;
    if (metaVersion != null && metaVersion.startsWith('2.')) {
      dataBytes = convert.hex.decode(encoded) as Uint8List;
      assert((() {
        final hash = dataString.getAttribute(_nodeHash);
        if (hash == null) {
          throw const FormatException('Keyfile must contain a hash.');
        }
        final expectedHashBytes = convert.hex.decode(hash);
        final actualHash =
            crypto.sha256.convert(dataBytes).bytes.sublist(0, 4) as Uint8List;
        if (!ByteUtils.eq(expectedHashBytes, actualHash)) {
          throw const FormatException(
              'Corrupted keyfile. Hash does not match');
        }
        return true;
      })());
    } else {
      dataBytes = base64.decode(encoded);
    }
    _logger.finer('Decoded base64 of keyfile.');
    return KeyFileCredentials._(ProtectedValue.fromBinary(dataBytes));
  } catch (e, stackTrace) {
    _logger.warning(
        'Unable to parse key file as hex or XML, use as is.', e, stackTrace);
    final bytes = crypto.sha256.convert(keyFileContents).bytes as Uint8List;
    return KeyFileCredentials._(ProtectedValue.fromBinary(bytes));
  }
}