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