private VerifySignatureResult VerifyFileIntegrity()

in net/JetBrains.SignatureVerifier/src/Crypt/AuthenticodeSignatureVerifier.cs [138:193]


  private VerifySignatureResult VerifyFileIntegrity(
    [NotNull] SignedMessage signedMessage,
    [NotNull] ComputeHashInfo computeHashInfo,
    [NotNull] Stream stream,
    [NotNull] FileIntegrityVerificationParams fileIntegrityVerificationParams)
  {
    if (signedMessage == null) throw new ArgumentNullException(nameof(signedMessage));
    if (computeHashInfo == null) throw new ArgumentNullException(nameof(computeHashInfo));
    if (stream == null) throw new ArgumentNullException(nameof(stream));
    if (fileIntegrityVerificationParams == null) throw new ArgumentNullException(nameof(fileIntegrityVerificationParams));

    var signedDataTokens = GetIndirectDataTokens(signedMessage);

    bool hasValidSignatures = false;
    bool hasInvalidSignatures = false;

    var algorithms = signedDataTokens
      .Select(t => t.IndirectDataContent.DigestInfo.DigestAlgorithm);

    IDictionary<AlgorithmIdentifier, byte[]> hashes = HashUtil.ComputeHashes(stream, computeHashInfo, algorithms);

    foreach (var spcIndirectDataToken in signedDataTokens)
    {
      AlgorithmIdentifier algId = spcIndirectDataToken.IndirectDataContent.DigestInfo.DigestAlgorithm;

      var imageHash = hashes[algId];

      byte[] expectedHash = spcIndirectDataToken.IndirectDataContent.DigestInfo.GetDigest();

      if (imageHash.Length == expectedHash.Length && Arrays.FixedTimeEquals(imageHash, expectedHash))
      {
        hasValidSignatures = true;
      }
      else
      {
        hasInvalidSignatures = true;
        var algName = DigestUtilities.GetAlgorithmName(algId.Algorithm);
        if (!fileIntegrityVerificationParams.AllowHashMismatches)
        {
          _logger?.Warning($"Authenticode signature verification error: hash value mismatch for the algorithm {algName}");
          break;
        }

        _logger?.Warning($"Authenticode signature verification warning: hash value mismatch for the algorithm {algName}");
      }
    }

    VerifySignatureResult fileIntegrityVerificationResult = (hasValidSignatures, hasInvalidSignatures, fileIntegrityVerificationParams.AllowHashMismatches) switch
    {
      (false, false, _) => new VerifySignatureResult(VerifySignatureStatus.FileIntegrityDataNotFound),
      (true, _, true) => VerifySignatureResult.Valid,
      (true, false, _) => VerifySignatureResult.Valid,
      _ => new VerifySignatureResult(VerifySignatureStatus.InvalidFileHash),
    };
    return fileIntegrityVerificationResult;
  }