public static bool VerifyImageSignature(byte[] imageBytes, byte[] softwareID, byte[] hardwareID)
        {
            if (softwareID.Length != 8)
            {
                throw new ArgumentException("SoftwareID should be 8 bytes long");
            }

            if (hardwareID.Length != 8)
            {
                throw new ArgumentException("HardwareID should be 8 bytes long");
            }

            byte[] expectedHash = DecryptFileSignature(imageBytes);

            byte[] imageHeader = ByteReader.ReadBytes(imageBytes, 0, SecondaryExecutableHeader.Length);
            byte[] codeBytes   = SecondaryExecutableHelper.ExtractCode(imageBytes);

            HashAlgorithm hashAlgorithm;

            if (expectedHash.Length == 20)
            {
                hashAlgorithm = SHA1.Create();
            }
            else if (expectedHash.Length == 32)
            {
                hashAlgorithm = SHA256.Create();
            }
            else
            {
                throw new Exception("Unknown hash algorithm");
            }
            byte[] message = hashAlgorithm.ComputeHash(ByteUtils.Concatenate(imageHeader, codeBytes));
            byte[] hash    = HMAC(softwareID, hardwareID, message, hashAlgorithm);
            return(ByteUtils.AreByteArraysEqual(expectedHash, hash));
        }
        public static byte[] GetRootCertificateHash(byte[] imageBytes)
        {
            List <byte[]> certificates         = SecondaryExecutableHelper.ExtractCertificates(imageBytes);
            int           rootCertificateIndex = CertificateValidationHelper.GetRootCertificateIndex(certificates);

            if (rootCertificateIndex == -1)
            {
                return(null);
            }

            byte[] rootCertificate = certificates[rootCertificateIndex];
            return(SHA256.Create().ComputeHash(rootCertificate));
        }
        private static byte[] DecryptFileSignature(byte[] imageBytes)
        {
            List <byte[]> certificates = SecondaryExecutableHelper.ExtractCertificates(imageBytes);

            if (certificates.Count > 0)
            {
                byte[]        certificateBytes = certificates[0];
                byte[]        signatureBytes   = SecondaryExecutableHelper.ExtractSignature(imageBytes);
                RSAParameters rsaParameters    = CertificateHelper.GetRSAParameters(certificateBytes);
                byte[]        decodedHash      = RSAHelper.DecryptSignature(signatureBytes, rsaParameters);
                return(decodedHash);
            }
            else
            {
                throw new Exception("According to the header, the file does not contain a certificate");
            }
        }
        public static bool VerifyCertificateStore(byte[] imageBytes)
        {
            List <byte[]> certificates = SecondaryExecutableHelper.ExtractCertificates(imageBytes);

            return(CertificateValidationHelper.VerifyCertificateChain(certificates));
        }