コード例 #1
0
        public static CodeDirectoryBlob CreateCodeDirectoryBlob(int codeLength, string ident, string teamID)
        {
            HashType hashType = HashType.SHA1;
            int      pageSize = 4096;

            CodeDirectoryBlob codeDirectory = new CodeDirectoryBlob();

            codeDirectory.CodeLimit = (uint)codeLength;
            codeDirectory.HashType  = hashType;
            codeDirectory.HashSize  = (byte)HashAlgorithmHelper.GetHashLength(hashType);
            codeDirectory.PageSize  = pageSize;

            codeDirectory.Ident  = ident;
            codeDirectory.TeamID = teamID;
            // We put empty hashes as placeholder to ensure that the blob length will not change later.
            for (int index = 0; index < SpecialHashCount; index++)
            {
                codeDirectory.SpecialHashes.Add(new byte[codeDirectory.HashSize]);
            }
            int codeHashEntries = (int)Math.Ceiling((double)codeLength / pageSize);

            for (int index = 0; index < codeHashEntries; index++)
            {
                codeDirectory.CodeHashes.Add(new byte[codeDirectory.HashSize]);
            }

            return(codeDirectory);
        }
コード例 #2
0
        private static byte[] GenerateHashesPList(byte[] codeDirectoryBytes, byte[] alternativeCodeDirectory1Bytes)
        {
            PListFile      plist      = new PListFile();
            DictionaryNode rootNode   = new DictionaryNode();
            ArrayNode      hashesNode = new ArrayNode();

            hashesNode.Add(new DataNode(HashAlgorithmHelper.ComputeHash(HashType.SHA1, codeDirectoryBytes)));
            hashesNode.Add(new DataNode(HashAlgorithmHelper.ComputeHash(HashType.SHA256Truncated, alternativeCodeDirectory1Bytes)));
            rootNode.Add("cdhashes", hashesNode);
            plist.RootNode = rootNode;
            return(plist.GetBytes(PListFormat.Xml));
        }
コード例 #3
0
        public static void UpdateHashes(CodeDirectoryBlob codeDirectory, byte[] codeToHash, byte[] infoFileBytes, CodeRequirementsBlob codeRequirements, byte[] codeResourcesBytes, EntitlementsBlob entitlements)
        {
            codeDirectory.CodeHashes = HashAlgorithmHelper.ComputeHashes(codeDirectory.HashType, codeDirectory.PageSize, codeToHash);

            codeDirectory.SpecialHashes = new List <byte[]>();
            codeDirectory.SpecialHashes.Insert(0, (HashAlgorithmHelper.ComputeHash(codeDirectory.HashType, infoFileBytes)));
            codeDirectory.SpecialHashes.Insert(0, (HashAlgorithmHelper.ComputeHash(codeDirectory.HashType, codeRequirements.GetBytes())));
            codeDirectory.SpecialHashes.Insert(0, (HashAlgorithmHelper.ComputeHash(codeDirectory.HashType, codeResourcesBytes)));
            if (SpecialHashCount >= CodeDirectoryBlob.ApplicationSpecificHashOffset)
            {
                codeDirectory.SpecialHashes.Insert(0, new byte[HashAlgorithmHelper.GetHashLength(codeDirectory.HashType)]);
                if (SpecialHashCount >= CodeDirectoryBlob.EntitlementsHashOffset)
                {
                    codeDirectory.SpecialHashes.Insert(0, (HashAlgorithmHelper.ComputeHash(codeDirectory.HashType, entitlements.GetBytes())));
                }
            }
        }
コード例 #4
0
        public static bool ValidateSpecialHashes(MachObjectFile file, byte[] infoFileBytes, byte[] codeResourcesBytes)
        {
            byte[] codeSignatureBytes = file.GetCodeSignatureBytes();
            if (CodeSignatureSuperBlob.IsCodeSignatureSuperBlob(codeSignatureBytes, 0))
            {
                CodeSignatureSuperBlob codeSignature = new CodeSignatureSuperBlob(codeSignatureBytes, 0);
                CodeDirectoryBlob      codeDirectory = codeSignature.GetEntry(CodeSignatureEntryType.CodeDirectory) as CodeDirectoryBlob;

                byte[] infoFileHash = HashAlgorithmHelper.ComputeHash(codeDirectory.HashType, infoFileBytes);
                if (!ByteUtils.AreByteArraysEqual(infoFileHash, codeDirectory.SpecialHashes[codeDirectory.SpecialHashes.Count - CodeDirectoryBlob.InfoFileHashOffset]))
                {
                    return(false);
                }

                byte[] codeResourcesHash = HashAlgorithmHelper.ComputeHash(codeDirectory.HashType, codeResourcesBytes);
                if (!ByteUtils.AreByteArraysEqual(codeResourcesHash, codeDirectory.SpecialHashes[codeDirectory.SpecialHashes.Count - CodeDirectoryBlob.CodeResourcesFileHashOffset]))
                {
                    return(false);
                }

                CodeRequirementsBlob codeRequirements = codeSignature.GetEntry(CodeSignatureEntryType.Requirements) as CodeRequirementsBlob;
                byte[] codeRequirementsBytes          = codeRequirements.GetBytes();
                byte[] codeRequirementsHash           = HashAlgorithmHelper.ComputeHash(codeDirectory.HashType, codeRequirementsBytes);
                if (!ByteUtils.AreByteArraysEqual(codeRequirementsHash, codeDirectory.SpecialHashes[codeDirectory.SpecialHashes.Count - CodeDirectoryBlob.RequirementsHashOffset]))
                {
                    return(false);
                }

                if (codeDirectory.SpecialHashes.Count >= CodeDirectoryBlob.EntitlementsHashOffset)
                {
                    CodeSignatureGenericBlob entitlements = codeSignature.GetEntry(CodeSignatureEntryType.Entitlements) as CodeSignatureGenericBlob;
                    byte[] entitlementsBytes = entitlements.GetBytes();
                    byte[] entitlementsHash  = HashAlgorithmHelper.ComputeHash(codeDirectory.HashType, entitlementsBytes);
                    if (!ByteUtils.AreByteArraysEqual(entitlementsHash, codeDirectory.SpecialHashes[codeDirectory.SpecialHashes.Count - CodeDirectoryBlob.EntitlementsHashOffset]))
                    {
                        return(false);
                    }
                }
                return(true);
            }
            return(false);
        }
コード例 #5
0
 public static bool ValidateExecutableHash(MachObjectFile file)
 {
     byte[] codeSignatureBytes = file.GetCodeSignatureBytes();
     if (CodeSignatureSuperBlob.IsCodeSignatureSuperBlob(codeSignatureBytes, 0))
     {
         CodeSignatureSuperBlob codeSignature = new CodeSignatureSuperBlob(codeSignatureBytes, 0);
         CodeDirectoryBlob      codeDirectory = codeSignature.GetEntry(CodeSignatureEntryType.CodeDirectory) as CodeDirectoryBlob;
         byte[]        signedFileData         = ByteReader.ReadBytes(file.GetBytes(), 0, (int)codeDirectory.CodeLimit);
         List <byte[]> hashes = HashAlgorithmHelper.ComputeHashes(codeDirectory.HashType, codeDirectory.PageSize, signedFileData);
         if (hashes.Count != codeDirectory.CodeHashes.Count)
         {
             return(false);
         }
         for (int index = 0; index < hashes.Count; index++)
         {
             if (!ByteUtils.AreByteArraysEqual(hashes[index], codeDirectory.CodeHashes[index]))
             {
                 return(false);
             }
         }
         return(true);
     }
     return(false);
 }