public VerifySignatureResult VerifyCDHashes()

in net/JetBrains.SignatureVerifier/src/Crypt/AppleSignatureVerifier.cs [71:138]


  public VerifySignatureResult VerifyCDHashes(Stream stream, IEnumerable<CDHash> cdHashesInfo, SignedMessage sectionSignature)
  {
    Dictionary<AlgorithmIdentifier, byte[]> hashesToVerify = new Dictionary<AlgorithmIdentifier, byte[]>();

    foreach (var cdHash in cdHashesInfo)
    {
      var hashId = new AlgorithmIdentifier(DigestUtilities.GetObjectIdentifier(cdHash.HashName));
      var hashValue = HashUtil.ComputeHash(stream, cdHash.ComputeHashInfo, hashId);

      hashesToVerify.Add(hashId, hashValue);
    }

    // Checking APPLE_HASH_AGILITY_V2 attribute for CDHash values
    var expectedCdHashValues = GetHashAgilityV2Hashes(sectionSignature);

    foreach (var cdHashValue in expectedCdHashValues)
    {
      AlgorithmIdentifier algId = cdHashValue.DigestAlgorithm;

      if (hashesToVerify.ContainsKey(algId))
      {
        var hashValue = hashesToVerify[algId];
        var expectedDigest = cdHashValue.GetDigest();

        int length = Math.Min(expectedDigest.Length, hashValue.Length);

        bool equals = Arrays.FixedTimeEquals( length, expectedDigest, 0, hashValue, 0);

        if (equals)
          hashesToVerify.Remove(algId);
        else
        {
          _logger?.Warning("Apple signature verification failed: CDHash value doesn't match the expected value");
          return new VerifySignatureResult(VerifySignatureStatus.InvalidFileHash);
        }
      }
    }

    if (hashesToVerify.Count == 0)
      return VerifySignatureResult.Valid;

    // Fallback for older APPLE_HASH_AGILITY attribute
    var expectedHashValues = GetHashAgilityV1Hashes(sectionSignature);

    foreach (var expectedHashValue in expectedHashValues)
    {
      AlgorithmIdentifier foundKey = null;

      foreach (var hashToVerifyKeyPair in hashesToVerify)
      {
        int length = Math.Min(expectedHashValue.Length, hashToVerifyKeyPair.Value.Length);

        if (Arrays.FixedTimeEquals(length, expectedHashValue, 0, hashToVerifyKeyPair.Value, 0))
        {
          foundKey = hashToVerifyKeyPair.Key;
          break;
        }
      }

      if (foundKey != null)
        hashesToVerify.Remove(foundKey);
    }

    if (hashesToVerify.Count > 0)
      _logger?.Warning("Apple signature verification failed: CDHash value doesn't match the expected value");

    return hashesToVerify.Count == 0 ? VerifySignatureResult.Valid : new VerifySignatureResult(VerifySignatureStatus.InvalidFileHash);
  }