public RuleResult Validate(IReadOnlyList <ICmsSignature> graph, SignatureLogger verboseWriter, CheckConfiguration configuration)
        {
            var signatures = graph.VisitAll(SignatureKind.AnySignature, deep: true);
            var result     = RuleResult.Pass;

            foreach (var signature in signatures)
            {
                if (signature.DigestAlgorithm.Value == KnownOids.MD2)
                {
                    verboseWriter.LogSignatureMessage(signature, $"Uses the {nameof(KnownOids.MD2)} digest algorithm.");
                    result = RuleResult.Fail;
                }
                else if (signature.DigestAlgorithm.Value == KnownOids.MD4)
                {
                    verboseWriter.LogSignatureMessage(signature, $"Uses the {nameof(KnownOids.MD4)} digest algorithm.");
                    result = RuleResult.Fail;
                }
                else if (signature.DigestAlgorithm.Value == KnownOids.MD5)
                {
                    verboseWriter.LogSignatureMessage(signature, $"Uses the {nameof(KnownOids.MD5)} digest algorithm.");
                    result = RuleResult.Fail;
                }
            }
            return(result);
        }
        public TestResult Validate(IReadOnlyList <ICmsSignature> graph, SignatureLogger verboseWriter, CheckConfiguration configuration)
        {
            var signatures = graph.VisitAll(SignatureKind.AnySignature, deep: true);
            var result     = TestResult.Pass;

            foreach (var signature in signatures)
            {
                var certificates = signature.AdditionalCertificates;
                using (var chain = new X509Chain())
                {
                    chain.ChainPolicy.ExtraStore.AddRange(certificates);
                    chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
                    //The purpose of this check is not to validate the chain, completely.
                    //The chain is needed so we know which certificate is the root and intermediates so we know which to validate and which not to validate.
                    //It is possible to have a valid Authenticode signature if the certificate is expired but was
                    //timestamped while it was valid. In this case we still want to successfully build a chain to perform validation.
                    chain.ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreNotTimeValid;
                    bool success = chain.Build(signature.Certificate);
                    if (!success)
                    {
                        verboseWriter.LogSignatureMessage(signature, $"Cannot build a chain successfully with signing certificate {signature.Certificate.SerialNumber}.");
                        result = TestResult.Fail;
                        continue;
                    }
                    if (!ValidateChain(signature, chain, verboseWriter))
                    {
                        result = TestResult.Fail;
                    }
                }
            }
            return(result);
        }
Beispiel #3
0
        public RuleResult Validate(IReadOnlyList <ISignature> graph, SignatureLogger verboseWriter, CheckConfiguration configuration)
        {
            var signatures = graph.VisitAll(SignatureKind.Any | SignatureKind.Deep);
            var result     = RuleResult.Pass;

            foreach (var signature in signatures)
            {
                var keyInfo = BitStrengthCalculator.CalculateStrength(signature.Certificate);
                switch (keyInfo.AlgorithmName)
                {
                case PublicKeyAlgorithm.ECDSA:
                    if (keyInfo.BitSize == null)
                    {
                        verboseWriter.LogSignatureMessage(signature, "Signature uses ECDSA with an unknown curve.");
                        result = RuleResult.Fail;
                    }
                    else if (keyInfo.BitSize > MAX_ECDSA_KEY_SIZE)
                    {
                        verboseWriter.LogSignatureMessage(signature, $"Signature uses ECDSA signature with a key size of {keyInfo.BitSize} exeeding maximum size of {MAX_ECDSA_KEY_SIZE}.");
                        result = RuleResult.Fail;
                    }
                    break;

                case PublicKeyAlgorithm.RSA:
                    if (keyInfo.BitSize == null)
                    {
                        verboseWriter.LogSignatureMessage(signature, "Signature has an unknown RSA key size.");
                        result = RuleResult.Fail;
                    }
                    else if (keyInfo.BitSize > MAX_RSA_KEY_SIZE)
                    {
                        verboseWriter.LogSignatureMessage(signature, $"Signature uses RSA signature with a key size of {keyInfo.BitSize} exeeding maximum size of {MAX_RSA_KEY_SIZE}.");
                        result = RuleResult.Fail;
                    }
                    break;

                case PublicKeyAlgorithm.DSA:
                    if (keyInfo.BitSize == null)
                    {
                        verboseWriter.LogSignatureMessage(signature, "Signature has an unknown DSA key size.");
                        result = RuleResult.Fail;
                    }
                    else if (keyInfo.BitSize > MAX_DSA_KEY_SIZE)
                    {
                        verboseWriter.LogSignatureMessage(signature, $"Signature uses DSA signature with a key size of {keyInfo.BitSize} exeeding maximum size of {MAX_DSA_KEY_SIZE}.");
                        result = RuleResult.Fail;
                    }
                    break;

                case PublicKeyAlgorithm.Other:
                    goto default;

                default:
                    verboseWriter.LogSignatureMessage(signature, $"Signature uses an unknown algorithm.");
                    result = RuleResult.Fail;
                    break;
                }
            }
            return(result);
        }
Beispiel #4
0
        public RuleResult Validate(IReadOnlyList <ISignature> graph, SignatureLogger verboseWriter, CheckConfiguration configuration)
        {
            var signatures = graph.VisitAll(SignatureKind.AnySignature);
            var result     = RuleResult.Pass;

            foreach (var signature in signatures)
            {
                var counterSignatures = signature.VisitAll(SignatureKind.AnyCounterSignature);
                foreach (var counterSignature in counterSignatures)
                {
                    foreach (var attribute in counterSignature.UnsignedAttributes)
                    {
                        if (!_trustedUnsignedAttributes.Contains(attribute.Oid.Value))
                        {
                            result = RuleResult.Fail;
                            var displayName = attribute.Oid.FriendlyName ?? "<no friendly name>";
                            verboseWriter.LogSignatureMessage(signature, $"Signature contains counter signer with unknown unsigned attribute {displayName} ({attribute.Oid.Value}).");
                        }
                    }
                }
                foreach (var attribute in signature.UnsignedAttributes)
                {
                    if (!_trustedUnsignedAttributes.Contains(attribute.Oid.Value))
                    {
                        result = RuleResult.Fail;
                        var displayName = attribute.Oid.FriendlyName ?? "<no friendly name>";
                        verboseWriter.LogSignatureMessage(signature, $"Signature contains unknown unsigned attribute {displayName} ({attribute.Oid.Value}).");
                    }
                }
            }
            return(result);
        }
        public TestResult Validate(IReadOnlyList <ICmsSignature> graph, SignatureLogger verboseWriter, CheckConfiguration configuration)
        {
            var signatures = graph.VisitAll(SignatureKind.AnySignature);
            var pass       = false;

            foreach (var signature in signatures)
            {
                string  serialNumber = "";
                string  KU           = "";
                Boolean KUCritical   = false;
                int     KU_extension = 0;

                string thumbprint = signature.Certificate.Thumbprint;
                serialNumber = signature.Certificate.SerialNumber;
                X509ExtensionCollection extensions = signature.Certificate.Extensions;
                foreach (X509Extension extension in extensions)
                {
                    //extension.Oid.FriendlyName
                    Console.WriteLine(extension.Oid.FriendlyName + "(" + extension.Oid.Value + ")");


                    if (extension.Oid.FriendlyName == "Key Usage")
                    {
                        X509KeyUsageExtension ext = (X509KeyUsageExtension)extension;
                        KUCritical = ext.Critical;
                        KU         = ext.KeyUsages.ToString();
                        Console.WriteLine(KU);
                        KU_extension++;
                    }
                }

                if (KU_extension == 1)
                {
                    if (KUCritical)
                    {
                        verboseWriter.LogSignatureMessage(signature, "Key Usage extension is marked critical.");
                        pass = true;
                    }
                    else
                    {
                        verboseWriter.LogSignatureMessage(signature, "Key Usage extension is not marked critical.");
                        pass = false;
                    }
                }
                else if (KU_extension == 0)
                {
                    verboseWriter.LogSignatureMessage(signature, "Signature does not have Key Usage extension.");
                    pass = false;
                }
                else if (KU_extension > 1)
                {
                    verboseWriter.LogSignatureMessage(signature, "Signature has duplicate Key Usage extension.");
                    pass = false;
                }
            }

            return(pass ? TestResult.Pass : TestResult.Fail);
        }
        public RuleResult Validate(IReadOnlyList <ICmsSignature> graph, SignatureLogger verboseWriter, CheckConfiguration configuration)
        {
            var signatures = graph.VisitAll(SignatureKind.Any | SignatureKind.Any);
            var result     = RuleResult.Pass;

            foreach (var signature in signatures)
            {
                var keyInfo = BitStrengthCalculator.CalculateStrength(signature.Certificate);
                switch (keyInfo.AlgorithmName)
                {
                case PublicKeyAlgorithm.ECDSA when keyInfo.BitSize is null:
                    verboseWriter.LogSignatureMessage(signature, "Signature uses ECDSA with an unknown curve.");
                    result = RuleResult.Fail;
                    break;

                case PublicKeyAlgorithm.ECDSA when keyInfo.BitSize < MIN_ECDSA_KEY_SIZE:
                    verboseWriter.LogSignatureMessage(signature, $"Signature uses a ECDSA key of size {keyInfo.BitSize} which is below the recommended {MIN_ECDSA_KEY_SIZE}.");
                    result = RuleResult.Fail;
                    break;

                case PublicKeyAlgorithm.ECDSA:
                    break;

                case PublicKeyAlgorithm.RSA when keyInfo.BitSize is null:
                    verboseWriter.LogSignatureMessage(signature, "Signature has an unknown RSA key size.");
                    result = RuleResult.Fail;
                    break;

                case PublicKeyAlgorithm.RSA when keyInfo.BitSize < MIN_RSADSA_KEY_SIZE:
                    verboseWriter.LogSignatureMessage(signature, $"Signature uses a RSA key of size {keyInfo.BitSize} which is below the recommended {MIN_RSADSA_KEY_SIZE}.");
                    result = RuleResult.Fail;
                    break;

                case PublicKeyAlgorithm.RSA when keyInfo.BitSize >= MIN_RSADSA_KEY_SIZE:
                    break;

                case PublicKeyAlgorithm.DSA when keyInfo.BitSize is null:
                    verboseWriter.LogSignatureMessage(signature, "Signature has an unknown DSA key size.");
                    result = RuleResult.Fail;
                    break;

                case PublicKeyAlgorithm.DSA when keyInfo.BitSize < MIN_RSADSA_KEY_SIZE:
                    //Effectively, 1024 is the max for a DSA key, so this will likely always fail.
                    verboseWriter.LogSignatureMessage(signature, $"Signature uses a DSA key of size {keyInfo.BitSize} which is below the recommended {MIN_RSADSA_KEY_SIZE}.");
                    result = RuleResult.Fail;
                    break;

                case PublicKeyAlgorithm.DSA:
                    break;

                default:
                    verboseWriter.LogSignatureMessage(signature, $"Signature uses an unknown algorithm.");
                    result = RuleResult.Fail;
                    break;
                }
            }
            return(result);
        }
        public RuleResult Validate(IReadOnlyList <ISignature> graph, SignatureLogger verboseWriter, CheckConfiguration configuration)
        {
            var signatures = graph.VisitAll(SignatureKind.Any | SignatureKind.Any);
            var result     = RuleResult.Pass;

            foreach (var signature in signatures)
            {
                var keyInfo = BitStrengthCalculator.CalculateStrength(signature.Certificate);
                switch (keyInfo.AlgorithmName)
                {
                case PublicKeyAlgorithm.ECDSA:
                    if (keyInfo.BitSize == null)
                    {
                        verboseWriter.LogSignatureMessage(signature, "Signature uses ECDSA with an unknown curve.");
                        result = RuleResult.Fail;
                    }
                    //We don't actually check the key size for ECDSA since all known values are acceptable.
                    break;

                case PublicKeyAlgorithm.RSA:
                    if (keyInfo.BitSize == null)
                    {
                        verboseWriter.LogSignatureMessage(signature, "Signature has an unknown RSA key size.");
                        result = RuleResult.Fail;
                    }
                    else if (keyInfo.BitSize < MIN_RSADSA_KEY_SIZE)
                    {
                        verboseWriter.LogSignatureMessage(signature, $"Signature uses a RSA key of size {keyInfo.BitSize} which is below the recommended {MIN_RSADSA_KEY_SIZE}.");
                        result = RuleResult.Fail;
                    }
                    break;

                case PublicKeyAlgorithm.DSA:
                    if (keyInfo.BitSize == null)
                    {
                        verboseWriter.LogSignatureMessage(signature, "Signature has an unknown DSA key size.");
                        result = RuleResult.Fail;
                    }
                    else if (keyInfo.BitSize < MIN_RSADSA_KEY_SIZE)
                    {
                        //Effectively, 1024 is the max for a DSA key, so this will likely always fail.
                        verboseWriter.LogSignatureMessage(signature, $"Signature uses a DSA key of size {keyInfo.BitSize} which is below the recommended {MIN_RSADSA_KEY_SIZE}.");
                        result = RuleResult.Fail;
                    }
                    break;

                case PublicKeyAlgorithm.Other:
                    goto default;

                default:
                    verboseWriter.LogSignatureMessage(signature, $"Signature uses an unknown algorithm.");
                    result = RuleResult.Fail;
                    break;
                }
            }
            return(result);
        }
Beispiel #8
0
        public RuleResult Validate(string file, SignatureLogger verboseWriter, CheckConfiguration configuration)
        {
            var padding = CertificatePaddingExtractor.ExtractPadding(file);

            if (padding?.Any(p => p != 0) == true)
            {
                verboseWriter.LogMessage($"Non-zero data found after PKCS#7 structure: {Convert.ToBase64String(padding)}.");
                return(RuleResult.Fail);
            }
            return(RuleResult.Pass);
        }
Beispiel #9
0
        public RuleResult Validate(string file, SignatureLogger verboseWriter, CheckConfiguration configuration)
        {
            var inspector = new FileInspector(file);
            var result    = inspector.Validate(configuration.RevocationMode);

            if (result == SignatureCheckResult.Valid)
            {
                return(RuleResult.Pass);
            }
            verboseWriter.LogMessage($"Authenticode signature validation failed with '{result}'.");
            return(RuleResult.Fail);
        }
Beispiel #10
0
        public RuleResult Validate(IReadOnlyList <ICmsSignature> graph, SignatureLogger verboseWriter, CheckConfiguration configuration)
        {
            var signatures = graph.VisitAll(SignatureKind.AnySignature);

            if (signatures.Any(s =>
                               s.DigestAlgorithm.Value == KnownOids.SHA256 ||
                               s.DigestAlgorithm.Value == KnownOids.SHA384 ||
                               s.DigestAlgorithm.Value == KnownOids.SHA512))
            {
                return(RuleResult.Pass);
            }
            return(RuleResult.Fail);
        }
Beispiel #11
0
 public RuleResult Validate(IReadOnlyList <ICmsSignature> graph, SignatureLogger verboseWriter, CheckConfiguration configuration)
 {
     if (graph.Count == 0)
     {
         return(RuleResult.Fail);
     }
     if (graph.Count > 1)
     {
         verboseWriter.LogMessage("Multiple primary signatures exist.");
         return(RuleResult.Fail);
     }
     return(RuleResult.Pass);
 }
        public TestResult Validate(IReadOnlyList <ICmsSignature> graph, SignatureLogger verboseWriter, CheckConfiguration configuration)
        {
            var     signatures    = graph.VisitAll(SignatureKind.AnySignature);
            int     AIA_extension = 0;
            Boolean AIACritical   = false;
            string  authorityInformationAccess = "";
            var     pass = false;

            foreach (var signature in signatures)
            {
                string serialNumber = "";
                AIA_extension = 0;
                AIACritical   = false;
                authorityInformationAccess = "";

                string thumbprint = signature.Certificate.Thumbprint;
                var    digestStr  = HashHelpers.GetHashForSignature(signature);//message digest of siganture(signature->details->advance->msg digest)
                serialNumber = signature.Certificate.SerialNumber;
                X509ExtensionCollection extensions = signature.Certificate.Extensions;
                foreach (X509Extension extension in extensions)
                {
                    /*This extension MUST be present and MUST NOT be marked critical.
                     * The extension MUST contain the HTTP URL of the CA’s OCSP responder (accessMethod = 1.3.6.1.5.5.7.48.1)
                     * and the HTTP URL for the Root CA’s certificate (accessMethod = 1.3.6.1.5.5.7.48.2).*/

                    if (extension.Oid.FriendlyName == "Authority Information Access")
                    {
                        if (AIA_extension != 0)
                        {
                            authorityInformationAccess = extension.Format(true);
                            AIACritical = extension.Critical;
                        }
                        Console.WriteLine(authorityInformationAccess);
                    }
                }

                if (authorityInformationAccess != "" && authorityInformationAccess.Contains("http://") && !AIACritical)
                {
                    verboseWriter.LogSignatureMessage(signature, "Signature has properly provided OCSP distribution point.");
                    pass = true;
                }
                else
                {
                    verboseWriter.LogSignatureMessage(signature, "Signature has not properly provided OCSP distribution point.");
                    pass = false;
                }
            }

            return(pass ? TestResult.Pass : TestResult.Fail);
        }
        public RuleResult Validate(IReadOnlyList <ICmsSignature> graph, SignatureLogger verboseWriter, CheckConfiguration configuration)
        {
            if (graph.Count == 0)
            {
                return(RuleResult.Fail);
            }
            var primary = graph[0];

            if (primary.DigestAlgorithm.Value != KnownOids.SHA1)
            {
                verboseWriter.LogSignatureMessage(primary, $"Expected {nameof(KnownOids.SHA1)} digest algorithm but is {primary.DigestAlgorithm.FriendlyName}.");
                return(RuleResult.Fail);
            }
            return(RuleResult.Pass);
        }
Beispiel #14
0
        public RuleResult Validate(IReadOnlyList <ISignature> graph, SignatureLogger verboseWriter, CheckConfiguration configuration)
        {
            var signatures = graph.VisitAll(SignatureKind.AnySignature | SignatureKind.Deep);
            var result     = RuleResult.Pass;

            foreach (var signature in signatures)
            {
                PublisherInformation info = null;
                foreach (var attribute in signature.SignedAttributes)
                {
                    if (attribute.Oid.Value == KnownOids.OpusInfo)
                    {
                        info = new PublisherInformation(attribute.Values[0]);
                        break;
                    }
                }
                if (info == null)
                {
                    result = RuleResult.Fail;
                    verboseWriter.LogSignatureMessage(signature, "Signature does not have any publisher information.");
                }
                else
                {
                    if (string.IsNullOrWhiteSpace(info.Description))
                    {
                        result = RuleResult.Fail;
                        verboseWriter.LogSignatureMessage(signature, "Signature does not have an accompanying description.");
                    }

                    if (string.IsNullOrWhiteSpace(info.UrlLink))
                    {
                        result = RuleResult.Fail;
                        verboseWriter.LogSignatureMessage(signature, "Signature does not have an accompanying URL.");
                    }
                    else
                    {
                        Uri uri;
                        if (!Uri.TryCreate(info.UrlLink, UriKind.Absolute, out uri))
                        {
                            result = RuleResult.Fail;
                            verboseWriter.LogSignatureMessage(signature, "Signature's accompanying URL is not a valid URI.");
                        }
                    }
                }
            }
            return(result);
        }
Beispiel #15
0
        public unsafe RuleResult Validate(string file, SignatureLogger verboseWriter, CheckConfiguration configuration)
        {
            var pathPtr = Marshal.StringToHGlobalUni(file);

            try
            {
                var flags           = WinTrustProviderFlags.NONE;
                var revocationFlags = WinTrustRevocationChecks.WTD_REVOKE_NONE;
                switch (configuration.RevocationMode)
                {
                case RevocationChecking.None:
                    flags |= WinTrustProviderFlags.WTD_REVOCATION_CHECK_NONE;
                    break;

                case RevocationChecking.Offline:
                    flags |= WinTrustProviderFlags.WTD_CACHE_ONLY_URL_RETRIEVAL;
                    goto default;

                default:
                    flags           |= WinTrustProviderFlags.WTD_REVOCATION_CHECK_CHAIN;
                    revocationFlags |= WinTrustRevocationChecks.WTD_REVOKE_WHOLECHAIN;
                    break;
                }
                var trust    = stackalloc WINTRUST_DATA[1];
                var fileInfo = stackalloc WINTRUST_FILE_INFO[1];
                trust->cbStruct                        = (uint)Marshal.SizeOf <WINTRUST_DATA>();
                trust->dwProvFlags                     = flags;
                trust->dwStateAction                   = WinTrustStateAction.WTD_STATEACTION_IGNORE;
                trust->dwUIChoice                      = WinTrustDataUIChoice.WTD_UI_NONE;
                trust->dwUIContext                     = WinTrustUIContext.WTD_UICONTEXT_EXECUTE;
                trust->dwUnionChoice                   = WinTrustUnionChoice.WTD_CHOICE_FILE;
                trust->fdwRevocationChecks             = revocationFlags;
                trust->trustUnion                      = new WINTRUST_DATA_UNION();
                trust->trustUnion.pFile                = fileInfo;
                trust->trustUnion.pFile->cbStruct      = (uint)Marshal.SizeOf <WINTRUST_FILE_INFO>();
                trust->trustUnion.pFile->pcwszFilePath = pathPtr;
                if (Wintrust.WinVerifyTrustEx(new IntPtr(-1), KnownGuids.WINTRUST_ACTION_GENERIC_VERIFY_V2, trust) == 0)
                {
                    return(RuleResult.Pass);
                }
                return(RuleResult.Fail);
            }
            finally
            {
                Marshal.FreeHGlobal(pathPtr);
            }
        }
Beispiel #16
0
        public TestResult Validate(IReadOnlyList <ICmsSignature> graph, SignatureLogger verboseWriter, CheckConfiguration configuration)
        {
            var signatures = graph.VisitAll(SignatureKind.AnySignature);
            var pass       = false;

            foreach (var signature in signatures)
            {
                string serialNumber = "";

                string  certificatePolicies           = "";
                Boolean CPCritical                    = false;
                int     certificatePolicies_extension = 0;

                string thumbprint = signature.Certificate.Thumbprint;
                serialNumber = signature.Certificate.SerialNumber;
                X509ExtensionCollection extensions = signature.Certificate.Extensions;
                foreach (X509Extension extension in extensions)
                {
                    //extension.Oid.FriendlyName
                    Console.WriteLine(extension.Oid.FriendlyName + "(" + extension.Oid.Value + ")");


                    if (extension.Oid.FriendlyName == "Certificate Policies")
                    {
                        certificatePolicies_extension = 1;
                        certificatePolicies           = extension.Format(true);
                        CPCritical = extension.Critical;
                        Console.WriteLine(certificatePolicies);
                    }
                }

                if (certificatePolicies_extension == 1)
                {
                    verboseWriter.LogSignatureMessage(signature, "has certificate policies extension.");
                    pass = true;
                }
                else
                {
                    verboseWriter.LogSignatureMessage(signature, "does not have certificate policies extension.");
                    pass = false;
                }
            }

            return(pass ? TestResult.Pass : TestResult.Fail);
        }
        public RuleResult Validate(IReadOnlyList <ISignature> graph, SignatureLogger verboseWriter, CheckConfiguration configuration)
        {
            var primary = graph.SingleOrDefault();

            //There are zero signatures.
            if (primary == null)
            {
                return(RuleResult.Fail);
            }
            var info = BitStrengthCalculator.CalculateStrength(primary.Certificate);

            if (info.AlgorithmName != PublicKeyAlgorithm.RSA && info.AlgorithmName != PublicKeyAlgorithm.DSA)
            {
                verboseWriter.LogSignatureMessage(primary, $"Primary signature should use RSA or DSA key but uses ${info.AlgorithmName.ToString()}");
                return(RuleResult.Fail);
            }
            return(RuleResult.Pass);
        }
        public RuleResult Validate(IReadOnlyList <ISignature> graph, SignatureLogger verboseWriter, CheckConfiguration configuration)
        {
            var result = RuleResult.Pass;
            //We exclude Authenticode timestamps because they cannot contain "additional" certificates but rather
            //Use their parent. Including Authenticode timestamps will produce duplicate warnings.
            var signatures = graph.VisitAll(SignatureKind.AnySignature | SignatureKind.Rfc3161Timestamp | SignatureKind.Deep);

            foreach (var signature in signatures)
            {
                var allEmbeddedCertificates           = signature.AdditionalCertificates.Cast <X509Certificate2>().ToList();
                var certificatesRequiringEliminiation = new HashSet <X509Certificate2>(allEmbeddedCertificates, new CertificateThumbprintComparer());
                foreach (var certificate in allEmbeddedCertificates)
                {
                    if (!certificatesRequiringEliminiation.Contains(certificate))
                    {
                        //This certificate was already eliminated because it was part of a previous chain.
                        continue;
                    }
                    using (var chain = new X509Chain())
                    {
                        chain.ChainPolicy.ExtraStore.AddRange(signature.AdditionalCertificates);
                        chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
                        chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
                        //All we care is that we can even find an authority.
                        chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags & ~X509VerificationFlags.AllowUnknownCertificateAuthority;
                        if (chain.Build(certificate))
                        {
                            certificatesRequiringEliminiation.ExceptWith(chain.ChainElements.Cast <X509ChainElement>().Select(c => c.Certificate));
                        }
                    }
                }
                if (certificatesRequiringEliminiation.Count > 0)
                {
                    foreach (var certificate in certificatesRequiringEliminiation)
                    {
                        verboseWriter.LogSignatureMessage(signature, $"Signature contained untrusted certificate \"{certificate.Subject}\" ({certificate.Thumbprint}).");
                    }
                    result = RuleResult.Fail;
                }
            }
            return(result);
        }
Beispiel #19
0
        public RuleResult Validate(IReadOnlyList <ICmsSignature> graph, SignatureLogger verboseWriter, CheckConfiguration configuration)
        {
            var signatures = graph.VisitAll(SignatureKind.AnySignature, deep: true);
            var result     = RuleResult.Pass;

            foreach (var signature in signatures)
            {
                PublisherInformation?info = null;
                foreach (var attribute in signature.SignedAttributes)
                {
                    if (attribute.Oid.Value == KnownOids.OpusInfo)
                    {
                        info = new PublisherInformation(attribute.Values[0]);
                        break;
                    }
                }
                if (info == null || info.IsEmpty)
                {
                    result = RuleResult.Fail;
                    verboseWriter.LogSignatureMessage(signature, "Signature does not have any publisher information.");
                }
                else
                {
                    if (string.IsNullOrWhiteSpace(info.UrlLink))
                    {
                        result = RuleResult.Fail;
                        verboseWriter.LogSignatureMessage(signature, "Signature does not have an accompanying URL.");
                    }
                    else if (!info.UrlLink.StartsWith(Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase))
                    {
                        result = RuleResult.Fail;
                        verboseWriter.LogSignatureMessage(signature, $"Signature's publisher information URL \"{info.UrlLink}\" does not use the secure HTTPS scheme.");
                    }
                }
            }
            return(result);
        }
Beispiel #20
0
        public unsafe RuleResult Validate(IReadOnlyList <ISignature> graph, SignatureLogger verboseWriter, CheckConfiguration configuration)
        {
            var signatures = graph.VisitAll(SignatureKind.AnySignature);
            var pass       = true;

            foreach (var signature in signatures)
            {
                var counterSignatures = signature.VisitAll(SignatureKind.AnyCounterSignature).ToList();
                var isSigned          = false;
                var strongSign        = false;
                foreach (var counterSignature in counterSignatures)
                {
                    isSigned = true;
                    if (counterSignature.DigestAlgorithm.Value == signature.DigestAlgorithm.Value)
                    {
                        strongSign = true;
                        break;
                    }
                }
                if (!isSigned && strongSign)
                {
                    throw new InvalidOperationException("Unexpectedly have a strong signature.");
                }
                if (!isSigned)
                {
                    verboseWriter.LogSignatureMessage(signature, "Signature is not timestamped.");
                    pass = false;
                }
                else if (!strongSign)
                {
                    verboseWriter.LogSignatureMessage(signature, $"Signature is not timestamped with the expected hash algorithm {signature.DigestAlgorithm.FriendlyName}.");
                    pass = false;
                }
            }
            return(pass ? RuleResult.Pass : RuleResult.Fail);
        }
        public TestResult Validate(IReadOnlyList <ICmsSignature> graph, SignatureLogger verboseWriter, CheckConfiguration configuration)
        {
            var signatures = graph.VisitAll(SignatureKind.AnySignature);
            var pass       = false;

            foreach (var signature in signatures)
            {
                string  serialNumber = "";
                string  crlDistPoint = "";
                Boolean crlCritical  = false;

                string thumbprint = signature.Certificate.Thumbprint;
                var    digestStr  = HashHelpers.GetHashForSignature(signature);//message digest of siganture(signature->details->advance->msg digest)
                serialNumber = signature.Certificate.SerialNumber;
                X509ExtensionCollection extensions = signature.Certificate.Extensions;
                foreach (X509Extension extension in extensions)
                {
                    if (extension.Oid.FriendlyName == "CRL Distribution Points")
                    {
                        /* This extension MAY be present.If present, it MUST NOT be marked critical,
                         * and it MUST contain the HTTP URL of the CA’s CRL service.*/
                        //Boolean crlHttpExists = false;
                        crlDistPoint = extension.Format(true);
                        crlCritical  = extension.Critical;
                        Console.WriteLine(crlDistPoint);

                        /*   if (crlDistPoint.Contains("http://"))
                         * {
                         *     //crlHttpExists = true;
                         *     Console.WriteLine("Has http crl");
                         * }
                         * if (crlDistPoint.Contains("ldap://"))
                         * {
                         *     Console.WriteLine("Has ldap crl");
                         *
                         * }*/
                    }
                }

                if (crlDistPoint != "")
                {
                    if (crlDistPoint.Contains("http://") && !crlCritical)
                    {
                        verboseWriter.LogSignatureMessage(signature, "Signature has properly provided CRL distribution point.");
                        pass = true;
                    }
                    else
                    {
                        verboseWriter.LogSignatureMessage(signature, "Signature has not properly provided CRL distribution point.");
                        pass = false;
                    }
                }
                else
                {
                    verboseWriter.LogSignatureMessage(signature, "Signature has not provided CRL distribution point.");
                    pass = false;
                }
            }

            return(pass ? TestResult.Pass : TestResult.Fail);
        }
Beispiel #22
0
        public TestResult Validate(IReadOnlyList <ICmsSignature> graph, SignatureLogger verboseWriter, CheckConfiguration configuration)
        {
            var signatures = graph.VisitAll(SignatureKind.AnySignature, deep: true);
            var result     = TestResult.Pass;

            foreach (var signature in signatures)
            {
                link        = "";
                Msg         = "";
                description = "";
                link        = "";
                PublisherInformation info = null;
                foreach (var attribute in signature.SignedAttributes)
                {
                    if (attribute.Oid.Value == KnownOids.OpusInfo)
                    {
                        info = new PublisherInformation(attribute.Values[0]);
                        break;
                    }
                }
                if (info == null || info.IsEmpty)
                {
                    result = TestResult.Fail;
                    Msg    = "Signature does not have any publisher information.";
                    verboseWriter.LogSignatureMessage(signature, "Signature does not have any publisher information.");
                }
                else
                {
                    if (string.IsNullOrWhiteSpace(info.Description))
                    {
                        result = TestResult.Fail;
                        Msg    = "Signature does not have an accompanying description.";
                        verboseWriter.LogSignatureMessage(signature, "Signature does not have an accompanying description.");
                    }

                    if (string.IsNullOrWhiteSpace(info.UrlLink))
                    {
                        result = TestResult.Fail;
                        Msg    = "Signature does not have an accompanying URL.";
                        verboseWriter.LogSignatureMessage(signature, "Signature does not have an accompanying URL.");
                    }
                    else
                    {
                        if (!Uri.TryCreate(info.UrlLink, UriKind.Absolute, out _))
                        {
                            result = TestResult.Fail;
                            Msg    = "Signature's accompanying URL is not a valid URI.";
                            verboseWriter.LogSignatureMessage(signature, "Signature's accompanying URL is not a valid URI.");
                        }
                    }
                }
                if (!string.IsNullOrWhiteSpace(info.UrlLink))
                {
                    link = info.UrlLink;
                }
                if (!string.IsNullOrWhiteSpace(info.Description))
                {
                    description = info.Description;
                }
                DBConnect.InsertPublisherTable(Program.appName, Program.fileName, link, signature.Certificate.Thumbprint, description, Msg);
            }
            return(result);
        }
 protected abstract bool ValidateChain(ICmsSignature signer, X509Chain chain, SignatureLogger verboseWriter);
        private static bool ValidatEKUForChain(ICmsSignature signature, X509Chain chain, SignatureLogger verboseWriter)
        {
            bool signingCertEKU = false;
            bool chainEKU       = false;
            X509ExtensionCollection extensions = signature.Certificate.Extensions;

            foreach (X509Extension extension in extensions)
            {
                if (extension.Oid.FriendlyName == "Enhanced Key Usage")
                {
                    signingCertEKU = true;
                    //break;
                    X509EnhancedKeyUsageExtension ext = (X509EnhancedKeyUsageExtension)extension;

                    OidCollection oids = ext.EnhancedKeyUsages;
                    EKUCritical = ext.Critical;

                    foreach (Oid oid in oids)
                    {
                        //if (oid.Equals("1.3.6.1.5.5.7.3.3"))


                        EKU_oidStr = oid.FriendlyName + "(" + oid.Value + ")" + ";" + EKU_oidStr;
                    }
                    Console.WriteLine(EKU_oidStr);
                }
            }
            string EKU =
                var signatureStrength = GetHashStrenghForComparison(signature.DigestAlgorithm.Value);
            var strongShaChain = true;
            var leafCertificateSignatureAlgorithm         = chain.ChainElements[0].Certificate.SignatureAlgorithm;
            var leafCertificateSignatureAlgorithmStrength = GetHashStrenghForComparison(leafCertificateSignatureAlgorithm.Value);

            //We use count-1 because we don't want to validate the root certificate.
            for (var i = 0; i < chain.ChainElements.Count - 1; i++)
            {
                var element                 = chain.ChainElements[i];
                var signatureAlgorithm      = element.Certificate.SignatureAlgorithm;
                var certificateHashStrength = GetHashStrenghForComparison(signatureAlgorithm.Value);
                if (certificateHashStrength < signatureStrength)
                {
                    verboseWriter.LogSignatureMessage(signature, $"Certificate {element.Certificate.Thumbprint} in chain uses {element.Certificate.SignatureAlgorithm.FriendlyName} for its signature algorithm instead of at least {signature.DigestAlgorithm.FriendlyName}.");
                    strongShaChain = false;
                }
                //Check that all intermediates are at least as strong as the leaf.
                else if (certificateHashStrength < leafCertificateSignatureAlgorithmStrength)
                {
                    verboseWriter.LogSignatureMessage(signature, $"Certificate {element.Certificate.Thumbprint} in chain uses {element.Certificate.SignatureAlgorithm.FriendlyName} for its signature algorithm instead of at least {signature.DigestAlgorithm.FriendlyName}.");
                }
            }
            return(strongShaChain);
        }
 protected override bool ValidateChain(ICmsSignature signer, X509Chain chain, SignatureLogger verboseWriter)
 {
     return(ValidatEKUForChain(signer, chain, verboseWriter));
 }
Beispiel #26
0
        public TestResult Validate(IReadOnlyList <ICmsSignature> graph, SignatureLogger verboseWriter, CheckConfiguration configuration)
        {
            var signatures     = graph.VisitAll(SignatureKind.AnySignature);
            var pass           = true;
            int signatureIndex = 0;

            foreach (var signature in signatures)
            {
                var    counterSignatures = signature.VisitAll(SignatureKind.AnyCounterSignature).ToList();
                int    ts             = counterSignatures.Count;
                var    isSigned       = false;
                var    strongSign     = 0;
                var    tsDigestString = "";
                string serialNumber   = "";
                string thumbprint     = signature.Certificate.Thumbprint;
                var    digestStr      = HashHelpers.GetHashForSignature(signature);//message digest of siganture(signature->details->advance->msg digest)
                DBConnect.InsertSignatureTable(Program.fileName, Program.appName, digestStr, signature.DigestAlgorithm.FriendlyName, signature.Certificate.Version, ts, thumbprint, signature.Certificate.Issuer, signature.Certificate.IssuerName.Name, signature.Certificate.Subject, signature.Certificate.SubjectName.Name, signatureIndex);
                System.DateTime notBeforeDate = signature.Certificate.NotBefore;
                System.DateTime notAfterDate  = signature.Certificate.NotAfter;
                serialNumber = signature.Certificate.SerialNumber;
                DBConnect.InsertSignatureDateTable(Program.appName, Program.fileName, digestStr, notBeforeDate.Year, notBeforeDate.Month, notBeforeDate.Day, notAfterDate.Year, notAfterDate.Month, notAfterDate.Day, thumbprint, signatureIndex);
                X509ExtensionCollection extensions = signature.Certificate.Extensions;

                int tssignatureIndex = 0;
                foreach (var counterSignature in counterSignatures)
                {
                    tsDigestString = HashHelpers.GetHashForSignature(counterSignature);//message digest of siganture(signature->details->advance->msg digest)
                    System.DateTime tsNotBeforeDate = counterSignature.Certificate.NotBefore;
                    System.DateTime tsNotAfterDate  = counterSignature.Certificate.NotAfter;

                    DBConnect.InsertTSSignatureDateTable(Program.appName, Program.fileName, tsDigestString, tsNotBeforeDate.Year, tsNotBeforeDate.Month, tsNotBeforeDate.Day, tsNotAfterDate.Year, tsNotAfterDate.Month, tsNotAfterDate.Day, counterSignature.Certificate.Thumbprint, tssignatureIndex);
                    isSigned = true;
                    if (counterSignature.DigestAlgorithm.Value == signature.DigestAlgorithm.Value)
                    {
                        strongSign++;
                        DBConnect.InsertTSSignatureTable(Program.appName, Program.fileName, tsDigestString, counterSignature.DigestAlgorithm.FriendlyName, counterSignature.Certificate.Version, 1, thumbprint, counterSignature.Certificate.Thumbprint, counterSignature.Certificate.Issuer, counterSignature.Certificate.IssuerName.Name, counterSignature.Certificate.Subject, counterSignature.Certificate.SubjectName.Name);
                    }
                    else
                    {
                        DBConnect.InsertTSSignatureTable(Program.appName, Program.fileName, tsDigestString, counterSignature.DigestAlgorithm.FriendlyName, counterSignature.Certificate.Version, 0, thumbprint, counterSignature.Certificate.Thumbprint, counterSignature.Certificate.Issuer, counterSignature.Certificate.IssuerName.Name, counterSignature.Certificate.Subject, counterSignature.Certificate.SubjectName.Name);
                    }
                }
                if (!isSigned && strongSign >= 1)
                {
                    throw new InvalidOperationException("Unexpectedly have a strong signature.");
                }
                if (!isSigned)
                {
                    verboseWriter.LogSignatureMessage(signature, "Signature is not timestamped.");
                    pass = false;
                }
                else if (strongSign == 0)
                {
                    verboseWriter.LogSignatureMessage(signature, $"Signature is not timestamped with the expected hash algorithm {signature.DigestAlgorithm.FriendlyName}.");
                    pass = false;
                }
                signatureIndex++;
            }

            return(pass ? TestResult.Pass : TestResult.Fail);
        }
Beispiel #27
0
        private static TestResult ValidateBasicConstraints(ICmsSignature signature, X509Chain chain, SignatureLogger verboseWriter)
        {
            var     pass          = false;
            Boolean BCCritical    = false;
            int     BC_extension  = 0;
            Boolean BC_CA         = false;
            Boolean hasPathLength = false;
            string  KU            = "";
            int     pathLength    = 0;
            string  issuer        = "";
            var     leafCertificateSignatureAlgorithm = chain.ChainElements[0].Certificate.SignatureAlgorithm;

            //We use count-1 because we don't want to validate the root certificate.
            for (var i = 0; i < chain.ChainElements.Count - 1; i++)
            {
                var element            = chain.ChainElements[i];
                var signatureAlgorithm = element.Certificate.SignatureAlgorithm;
                issuer = element.Certificate.Issuer;
                X509ExtensionCollection extensions = element.Certificate.Extensions;
                BC_extension  = 0;
                BC_CA         = false;
                hasPathLength = false;
                pathLength    = 0;
                KU            = "";

                foreach (X509Extension extension in extensions)
                {
                    if (extension.Oid.FriendlyName == "Basic Constraints")
                    {
                        X509BasicConstraintsExtension ext = (X509BasicConstraintsExtension)extension;
                        BCCritical = ext.Critical;

                        BC_extension++;
                        BC_CA         = ext.CertificateAuthority;
                        hasPathLength = ext.HasPathLengthConstraint;
                        pathLength    = ext.PathLengthConstraint;
                    }
                }

                /*   if (BC_extension == 0 && i>0)
                 * {
                 *        Console.WriteLine(issuer);
                 *        Console.WriteLine("No BC.");
                 *        Console.WriteLine(KU);
                 *        Console.WriteLine(Program.appName);
                 *        Console.WriteLine("==================================================================");
                 * }*/
                if (i == 0)
                {
                    if (BC_extension == 1 && !BC_CA)
                    {
                        pass = true;
                    }
                    else if (BC_extension > 1)
                    {
                        verboseWriter.LogSignatureMessage(signature, $"Signature has duplicate Basic Constraints extension.");
                        pass = false;
                    }
                    else if (BC_extension == 1 && BC_CA)
                    {
                        verboseWriter.LogSignatureMessage(signature, $"Signature has violating CA filed for Basic Constraints.");
                        pass = false;
                    }
                    else
                    {
                        pass = false;
                    }
                }
                else
                {
                    verboseWriter.LogSignatureMessage(signature, $"Not a leaf certificate.");
                }
            }
            return(pass ? TestResult.Pass : TestResult.Fail);
        }
        public TestResult Validate(IReadOnlyList <ICmsSignature> graph, SignatureLogger verboseWriter, CheckConfiguration configuration)
        {
            var signatures     = graph.VisitAll(SignatureKind.Any | SignatureKind.Any);
            var result         = TestResult.Pass;
            int signatureIndex = 0;

            foreach (var signature in signatures)
            {
                string thumbprint = signature.Certificate.Thumbprint;
                string errMsg     = "";
                int    keySize    = 0;
                var    keyInfo    = BitStrengthCalculator.CalculateStrength(signature.Certificate);
                if (!(keyInfo.BitSize is null))
                {
                    keySize = (int)keyInfo.BitSize;
                }
                string signatureAlgorithm = "";
                switch (keyInfo.AlgorithmName)
                {
                case PublicKeyAlgorithm.ECDSA when keyInfo.BitSize is null:
                    errMsg = "Signature uses ECDSA with an unknown curve.";
                    verboseWriter.LogSignatureMessage(signature, "Signature uses ECDSA with an unknown curve.");
                    signatureAlgorithm = "ECDSA";
                    result             = TestResult.Fail;
                    break;

                case PublicKeyAlgorithm.ECDSA when keyInfo.BitSize < MIN_ECDSA_KEY_SIZE:
                    errMsg = $"Signature uses a ECDSA key of size {keyInfo.BitSize} which is below the recommended {MIN_ECDSA_KEY_SIZE}.";
                    verboseWriter.LogSignatureMessage(signature, $"Signature uses a ECDSA key of size {keyInfo.BitSize} which is below the recommended {MIN_ECDSA_KEY_SIZE}.");
                    result             = TestResult.Fail;
                    signatureAlgorithm = "ECDSA";
                    break;

                case PublicKeyAlgorithm.ECDSA:
                    signatureAlgorithm = "ECDSA";
                    break;

                case PublicKeyAlgorithm.RSA when keyInfo.BitSize is null:
                    errMsg = "Signature has an unknown RSA key size.";
                    verboseWriter.LogSignatureMessage(signature, "Signature has an unknown RSA key size.");
                    result             = TestResult.Fail;
                    signatureAlgorithm = "RSA";
                    break;

                case PublicKeyAlgorithm.RSA when keyInfo.BitSize < MIN_RSADSA_KEY_SIZE:
                    errMsg = $"Signature uses a RSA key of size {keyInfo.BitSize} which is below the recommended {MIN_RSADSA_KEY_SIZE}.";
                    verboseWriter.LogSignatureMessage(signature, $"Signature uses a RSA key of size {keyInfo.BitSize} which is below the recommended {MIN_RSADSA_KEY_SIZE}.");
                    signatureAlgorithm = "RSA";
                    result             = TestResult.Fail;
                    break;

                case PublicKeyAlgorithm.RSA when keyInfo.BitSize >= MIN_RSADSA_KEY_SIZE:
                    signatureAlgorithm = "RSA";
                    break;

                case PublicKeyAlgorithm.DSA when keyInfo.BitSize is null:
                    errMsg = "Signature has an unknown DSA key size.";
                    verboseWriter.LogSignatureMessage(signature, "Signature has an unknown DSA key size.");
                    result             = TestResult.Fail;
                    signatureAlgorithm = "DSA";
                    break;

                case PublicKeyAlgorithm.DSA when keyInfo.BitSize < MIN_RSADSA_KEY_SIZE:
                    //Effectively, 1024 is the max for a DSA key, so this will likely always fail.
                    errMsg = $"Signature uses a DSA key of size {keyInfo.BitSize} which is below the recommended {MIN_RSADSA_KEY_SIZE}.";
                    verboseWriter.LogSignatureMessage(signature, $"Signature uses a DSA key of size {keyInfo.BitSize} which is below the recommended {MIN_RSADSA_KEY_SIZE}.");
                    result             = TestResult.Fail;
                    signatureAlgorithm = "DSA";
                    break;

                case PublicKeyAlgorithm.DSA:
                    signatureAlgorithm = "DSA";
                    break;

                default:
                    errMsg = $"Signature uses an unknown algorithm.";
                    verboseWriter.LogSignatureMessage(signature, $"Signature uses an unknown algorithm.");
                    result = TestResult.Fail;
                    break;
                }
                DBConnect.InsertPublicKeyInfo(Program.appName, Program.fileName, signatureAlgorithm, keySize, thumbprint, errMsg, signatureIndex);
                signatureIndex++;
            }
            return(result);
        }
        private static bool ValidateStrongChain(ICmsSignature signature, X509Chain chain, SignatureLogger verboseWriter)
        {
            var signatureStrength = GetHashStrenghForComparison(signature.DigestAlgorithm.Value !);
            var strongShaChain    = true;
            var leafCertificateSignatureAlgorithm         = chain.ChainElements[0].Certificate.SignatureAlgorithm;
            var leafCertificateSignatureAlgorithmStrength = GetHashStrenghForComparison(leafCertificateSignatureAlgorithm.Value !);

            //We use count-1 because we don't want to validate the root certificate.
            for (var i = 0; i < chain.ChainElements.Count - 1; i++)
            {
                var element                 = chain.ChainElements[i];
                var signatureAlgorithm      = element.Certificate.SignatureAlgorithm;
                var certificateHashStrength = GetHashStrenghForComparison(signatureAlgorithm.Value !);
                if (certificateHashStrength < signatureStrength)
                {
                    verboseWriter.LogSignatureMessage(signature, $"Certificate {element.Certificate.Thumbprint} in chain uses {element.Certificate.SignatureAlgorithm.FriendlyName} for its signature algorithm instead of at least {signature.DigestAlgorithm.FriendlyName}.");
                    strongShaChain = false;
                }
                //Check that all intermediates are at least as strong as the leaf.
                else if (certificateHashStrength < leafCertificateSignatureAlgorithmStrength)
                {
                    verboseWriter.LogSignatureMessage(signature, $"Certificate {element.Certificate.Thumbprint} in chain uses {element.Certificate.SignatureAlgorithm.FriendlyName} for its signature algorithm instead of at least {signature.DigestAlgorithm.FriendlyName}.");
                }
            }
            return(strongShaChain);
        }
        public TestResult Validate(IReadOnlyList <ICmsSignature> graph, SignatureLogger verboseWriter, CheckConfiguration configuration)
        {
            var signatures     = graph.VisitAll(SignatureKind.AnySignature);
            var pass           = true;
            int signatureIndex = 0;

            foreach (var signature in signatures)
            {
                string  repeatedExtension = "";
                var     counterSignatures = signature.VisitAll(SignatureKind.AnyCounterSignature).ToList();
                int     ts                         = counterSignatures.Count;
                var     isSigned                   = false;
                var     strongSign                 = 0;
                var     tsDigestString             = "";
                string  otherExtensions            = "";
                string  serialNumber               = "";
                int     pathLength                 = 0;
                Boolean BC_CA                      = false;
                Boolean hasPathLength              = false;
                string  KU                         = "";
                Boolean KUCritical                 = false;
                string  SKI                        = "";
                string  EKU_oidStr                 = "";
                string  AKI                        = "";
                string  certificatePolicies        = "";
                string  crlDistPoint               = "";
                string  authorityInformationAccess = "";
                Boolean crlCritical                = false;
                Boolean EKUCritical                = false;
                Boolean BCCritical                 = false;
                Boolean CPCritical                 = false;
                Boolean SKICritical                = false;
                Boolean AKICritical                = false;
                Boolean AIACritical                = false;
                // Boolean CS_EKU = false;
                int KU_extension  = 0;
                int EKU_extension = 0;
                int BC_extension  = 0;
                int SKI_extension = 0;
                int AKI_extension = 0;
                int crl_extension = 0;
                int CP_extension  = 0;
                int AIA_extension = 0;



                string thumbprint = signature.Certificate.Thumbprint;
                var    digestStr  = HashHelpers.GetHashForSignature(signature);//message digest of siganture(signature->details->advance->msg digest)
                DBConnect.InsertSignatureTable(Program.fileName, Program.appName, digestStr, signature.DigestAlgorithm.FriendlyName, signature.Certificate.Version, ts, thumbprint, signature.Certificate.Issuer, signature.Certificate.IssuerName.Name, signature.Certificate.Subject, signature.Certificate.SubjectName.Name, signatureIndex);
                System.DateTime notBeforeDate = signature.Certificate.NotBefore;
                System.DateTime notAfterDate  = signature.Certificate.NotAfter;
                serialNumber = signature.Certificate.SerialNumber;
                DBConnect.InsertSignatureDateTable(Program.appName, Program.fileName, digestStr, notBeforeDate.Year, notBeforeDate.Month, notBeforeDate.Day, notAfterDate.Year, notAfterDate.Month, notAfterDate.Day, thumbprint, signatureIndex);
                X509ExtensionCollection extensions = signature.Certificate.Extensions;
                foreach (X509Extension extension in extensions)
                {
                    //extension.Oid.FriendlyName
                    Console.WriteLine(extension.Oid.FriendlyName + "(" + extension.Oid.Value + ")");


                    if (extension.Oid.FriendlyName == "Key Usage")
                    {
                        X509KeyUsageExtension ext = (X509KeyUsageExtension)extension;
                        KUCritical = ext.Critical;
                        if (KU_extension != 0)
                        {
                            repeatedExtension += extension.Oid.FriendlyName + ",";
                        }
                        KU = ext.KeyUsages.ToString();
                        Console.WriteLine(KU);
                        KU_extension++;
                    }

                    else if (extension.Oid.FriendlyName == "Basic Constraints")
                    {
                        X509BasicConstraintsExtension ext = (X509BasicConstraintsExtension)extension;
                        BCCritical = ext.Critical;
                        if (BC_extension != 0)
                        {
                            repeatedExtension += extension.Oid.FriendlyName + ",";
                        }
                        BC_CA         = ext.CertificateAuthority;
                        hasPathLength = ext.HasPathLengthConstraint;
                        pathLength    = ext.PathLengthConstraint;
                        Console.WriteLine(BC_CA);
                        Console.WriteLine(hasPathLength);
                        Console.WriteLine(pathLength);
                        BC_extension++;
                    }

                    else if (extension.Oid.FriendlyName == "Subject Key Identifier")
                    {
                        X509SubjectKeyIdentifierExtension ext = (X509SubjectKeyIdentifierExtension)extension;
                        SKICritical = ext.Critical;
                        if (SKI_extension != 0)
                        {
                            repeatedExtension += extension.Oid.FriendlyName + ",";
                        }
                        SKI = ext.SubjectKeyIdentifier.ToString();
                        Console.WriteLine(SKI);
                        SKI_extension++;
                    }

                    else if (extension.Oid.FriendlyName == "Authority Key Identifier")
                    {
                        AKICritical = extension.Critical;
                        if (AKI_extension != 0)
                        {
                            repeatedExtension += extension.Oid.FriendlyName + ",";
                        }
                        AKI = extension.Format(true);
                        Console.WriteLine(AKI);
                        AKI_extension++;
                    }

                    else if (extension.Oid.FriendlyName == "Enhanced Key Usage")
                    {
                        if (EKU_extension != 0)
                        {
                            repeatedExtension += extension.Oid.FriendlyName + ",";
                        }
                        X509EnhancedKeyUsageExtension ext = (X509EnhancedKeyUsageExtension)extension;

                        OidCollection oids = ext.EnhancedKeyUsages;
                        EKUCritical = ext.Critical;

                        foreach (Oid oid in oids)
                        {
                            //if (oid.Equals("1.3.6.1.5.5.7.3.3"))


                            EKU_oidStr = oid.FriendlyName + "(" + oid.Value + ")" + ";" + EKU_oidStr;
                        }
                        Console.WriteLine(EKU_oidStr);
                        EKU_extension++;
                    }
                    else if (extension.Oid.FriendlyName == "CRL Distribution Points")
                    {
                        /*This extension MUST be present, MUST NOT be marked critical,
                         * and MUST contain the HTTP URL of the CA’s CRL service*/
                        //Boolean crlHttpExists = false;
                        if (crl_extension != 0)
                        {
                            repeatedExtension += extension.Oid.FriendlyName + ",";
                        }
                        crlDistPoint = extension.Format(true);
                        crlCritical  = extension.Critical;
                        Console.WriteLine(crlDistPoint);
                        if (crlDistPoint.Contains("http://"))
                        {
                            //crlHttpExists = true;
                            Console.WriteLine("has http crl");
                        }
                        if (crlDistPoint.Contains("ldap://"))
                        {
                            Console.WriteLine("has ldap crl");
                        }
                        crl_extension++;
                    }
                    else if (extension.Oid.FriendlyName == "Certificate Policies")
                    {
                        if (CP_extension != 0)
                        {
                            repeatedExtension += extension.Oid.FriendlyName + ",";
                        }
                        certificatePolicies = extension.Format(true);
                        CPCritical          = extension.Critical;
                        Console.WriteLine(certificatePolicies);
                        CP_extension++;
                    }

                    else if (extension.Oid.FriendlyName == "Authority Information Access")
                    {
                        if (AIA_extension != 0)
                        {
                            repeatedExtension += extension.Oid.FriendlyName + ",";
                        }
                        authorityInformationAccess = extension.Format(true);
                        AIACritical = extension.Critical;
                        Console.WriteLine(authorityInformationAccess);
                        AIA_extension++;
                    }

                    else
                    {
                        otherExtensions += ";" + extension.Oid.FriendlyName + "(" + extension.Oid.Value.ToString() + ")";
                    }
                }
                DBConnect.InsertRepeatedExtensionsTable(Program.appName, Program.fileName, repeatedExtension, thumbprint);
                DBConnect.InsertExtensionsTable(Program.appName, Program.fileName, digestStr, serialNumber, Convert.ToInt32(BC_CA), pathLength, Convert.ToInt32(hasPathLength), KU, SKI, EKU_oidStr, AKI, certificatePolicies, crlDistPoint, Convert.ToInt32(crlCritical), Convert.ToInt32(EKUCritical), Convert.ToInt32(KUCritical), Convert.ToInt32(BCCritical), Convert.ToInt32(CPCritical), Convert.ToInt32(SKICritical), Convert.ToInt32(AKICritical), otherExtensions, authorityInformationAccess, Convert.ToInt32(AIACritical), thumbprint, signatureIndex);
                Validation.validateWithSignTool(Program.filePath, signatureIndex, thumbprint);
                int tssignatureIndex = 0;
                foreach (var counterSignature in counterSignatures)
                {
                    //reset extensions' values
                    otherExtensions = "";
                    serialNumber    = "";
                    pathLength      = 0;
                    BC_CA           = false;
                    hasPathLength   = false;
                    KU                         = "";
                    KUCritical                 = false;
                    SKI                        = "";
                    EKU_oidStr                 = "";
                    AKI                        = "";
                    certificatePolicies        = "";
                    crlDistPoint               = "";
                    authorityInformationAccess = "";
                    crlCritical                = false;
                    EKUCritical                = false;
                    BCCritical                 = false;
                    CPCritical                 = false;
                    SKICritical                = false;
                    AKICritical                = false;
                    AIACritical                = false;

                    tsDigestString = HashHelpers.GetHashForSignature(counterSignature);//message digest of siganture(signature->details->advance->msg digest)
                    System.DateTime tsNotBeforeDate = counterSignature.Certificate.NotBefore;
                    System.DateTime tsNotAfterDate  = counterSignature.Certificate.NotAfter;

                    DBConnect.InsertTSSignatureDateTable(Program.appName, Program.fileName, tsDigestString, tsNotBeforeDate.Year, tsNotBeforeDate.Month, tsNotBeforeDate.Day, tsNotAfterDate.Year, tsNotAfterDate.Month, tsNotAfterDate.Day, counterSignature.Certificate.Thumbprint, tssignatureIndex);
                    isSigned = true;
                    if (counterSignature.DigestAlgorithm.Value == signature.DigestAlgorithm.Value)
                    {
                        strongSign++;
                        DBConnect.InsertTSSignatureTable(Program.appName, Program.fileName, tsDigestString, counterSignature.DigestAlgorithm.FriendlyName, counterSignature.Certificate.Version, 1, thumbprint, counterSignature.Certificate.Thumbprint, counterSignature.Certificate.Issuer, counterSignature.Certificate.IssuerName.Name, counterSignature.Certificate.Subject, counterSignature.Certificate.SubjectName.Name);
                    }
                    else
                    {
                        DBConnect.InsertTSSignatureTable(Program.appName, Program.fileName, tsDigestString, counterSignature.DigestAlgorithm.FriendlyName, counterSignature.Certificate.Version, 0, thumbprint, counterSignature.Certificate.Thumbprint, counterSignature.Certificate.Issuer, counterSignature.Certificate.IssuerName.Name, counterSignature.Certificate.Subject, counterSignature.Certificate.SubjectName.Name);
                    }


                    //extracting extensions of timestamp certificate

                    X509ExtensionCollection tsEextensions = signature.Certificate.Extensions;
                    foreach (X509Extension extension in tsEextensions)
                    {
                        //extension.Oid.FriendlyName
                        Console.WriteLine(extension.Oid.FriendlyName + "(" + extension.Oid.Value + ")");


                        if (extension.Oid.FriendlyName == "Key Usage")
                        {
                            X509KeyUsageExtension ext = (X509KeyUsageExtension)extension;
                            KUCritical = ext.Critical;
                            KU         = ext.KeyUsages.ToString();
                            Console.WriteLine(KU);
                        }

                        else if (extension.Oid.FriendlyName == "Basic Constraints")
                        {
                            X509BasicConstraintsExtension ext = (X509BasicConstraintsExtension)extension;
                            BCCritical    = ext.Critical;
                            BC_CA         = ext.CertificateAuthority;
                            hasPathLength = ext.HasPathLengthConstraint;
                            pathLength    = ext.PathLengthConstraint;
                            Console.WriteLine(BC_CA);
                            Console.WriteLine(hasPathLength);
                            Console.WriteLine(pathLength);
                        }

                        else if (extension.Oid.FriendlyName == "Subject Key Identifier")
                        {
                            X509SubjectKeyIdentifierExtension ext = (X509SubjectKeyIdentifierExtension)extension;
                            SKICritical = ext.Critical;
                            SKI         = ext.SubjectKeyIdentifier.ToString();
                            Console.WriteLine(SKI);
                        }

                        else if (extension.Oid.FriendlyName == "Authority Key Identifier")
                        {
                            AKICritical = extension.Critical;
                            AKI         = extension.Format(true);
                            Console.WriteLine(AKI);
                        }

                        else if (extension.Oid.FriendlyName == "Enhanced Key Usage")
                        {
                            //Boolean CS_EKU;
                            X509EnhancedKeyUsageExtension ext = (X509EnhancedKeyUsageExtension)extension;
                            OidCollection oids = ext.EnhancedKeyUsages;
                            EKUCritical = ext.Critical;

                            foreach (Oid oid in oids)
                            {
                                //if (oid.Equals("1.3.6.1.5.5.7.3.3"))
                                //  CS_EKU = true;
                                EKU_oidStr = oid.FriendlyName + "(" + oid.Value + ")" + ";" + EKU_oidStr;
                            }
                            Console.WriteLine(EKU_oidStr);
                        }
                        else if (extension.Oid.FriendlyName == "CRL Distribution Points")
                        {
                            /*This extension MUST be present, MUST NOT be marked critical,
                             * and MUST contain the HTTP URL of the CA’s CRL service*/
                            //Boolean crlHttpExists = false;
                            crlDistPoint = extension.Format(true);
                            crlCritical  = extension.Critical;
                            Console.WriteLine(crlDistPoint);
                            if (crlDistPoint.Contains("http://"))
                            {
                                //crlHttpExists = true;
                                Console.WriteLine("has http crl");
                            }
                            if (crlDistPoint.Contains("ldap://"))
                            {
                                Console.WriteLine("has ldap crl");
                            }
                        }
                        else if (extension.Oid.FriendlyName == "Certificate Policies")
                        {
                            certificatePolicies = extension.Format(true);
                            CPCritical          = extension.Critical;
                            Console.WriteLine(certificatePolicies);
                        }

                        else if (extension.Oid.FriendlyName == "Authority Information Access")
                        {
                            authorityInformationAccess = extension.Format(true);
                            AIACritical = extension.Critical;
                            Console.WriteLine(authorityInformationAccess);
                        }

                        else
                        {
                            otherExtensions += ";" + extension.Oid.FriendlyName + "(" + extension.Oid.Value.ToString() + ")";
                        }
                    }
                    DBConnect.InsertTSExtensionsTable(Program.appName, Program.fileName, digestStr, serialNumber, Convert.ToInt32(BC_CA), pathLength, Convert.ToInt32(hasPathLength), KU, SKI, EKU_oidStr, AKI, certificatePolicies, crlDistPoint, Convert.ToInt32(crlCritical), Convert.ToInt32(EKUCritical), Convert.ToInt32(KUCritical), Convert.ToInt32(BCCritical), Convert.ToInt32(CPCritical), Convert.ToInt32(SKICritical), Convert.ToInt32(AKICritical), otherExtensions, authorityInformationAccess, Convert.ToInt32(AIACritical), thumbprint, tssignatureIndex);
                    tssignatureIndex++;
                }

                if (!isSigned && strongSign >= 1)
                {
                    throw new InvalidOperationException("Unexpectedly have a strong signature.");
                }
                if (!isSigned)
                {
                    verboseWriter.LogSignatureMessage(signature, "Signature is not timestamped.");
                    pass = false;
                }
                else if (strongSign == 0)
                {
                    verboseWriter.LogSignatureMessage(signature, $"Signature is not timestamped with the expected hash algorithm {signature.DigestAlgorithm.FriendlyName}.");
                    pass = false;
                }
                signatureIndex++;
            }

            return(pass ? TestResult.Pass : TestResult.Fail);
        }