public static void ShouldExtractSignatureDetails()
        {
            var extract = SignatureTreeInspector.Extract(_path);
            var root    = Assert.Single(extract);

            Assert.NotNull(root);
            Assert.Equal(SignatureKind.Signature, root.Kind);
            Assert.Equal(HashAlgorithmName.SHA256, root.DigestAlgorithmName);
            Assert.Equal("CN=Kevin Jones, O=Kevin Jones, L=Alexandria, S=VA, C=US", root.Certificate.Subject);
            Assert.Equal("1.2.840.113549.1.1.1", root.HashEncryptionAlgorithm.Value); //pkcs-1 rsaEncryption

            var timestamp = Assert.Single(root.VisitAll(SignatureKind.Rfc3161Timestamp, false));

            Assert.NotNull(timestamp);
            Assert.Equal(SignatureKind.Rfc3161Timestamp, timestamp.Kind);
            Assert.Equal(HashAlgorithmName.SHA256, timestamp.DigestAlgorithmName);
            Assert.Equal("CN=DigiCert SHA2 Timestamp Responder, O=DigiCert, C=US", timestamp.Certificate.Subject);
            Assert.Equal("1.2.840.113549.1.1.1", timestamp.HashEncryptionAlgorithm.Value); //pkcs-1 rsaEncryption
        }
Ejemplo n.º 2
0
        static int Main(string[] args)
        {
            if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Console.Error.WriteLine("AuthenticodeLint is only supported on Windows.");
                return(ExitCodes.PlatformNotSupported);
            }
            var cli = Environment.CommandLine;
            List <CommandLineParameter> parsedCommandLine;

            try
            {
                var commandLine = CommandLineParser.LexCommandLine(cli).Skip(1);
                parsedCommandLine = CommandLineParser.CreateCommandLineParametersWithValues(commandLine).ToList();
            }
            catch (InvalidOperationException)
            {
                parsedCommandLine = null;
            }

            if (parsedCommandLine == null || parsedCommandLine.Count == 0 || parsedCommandLine.Any(cl => cl.Name == "help"))
            {
                ShowHelp();
                //Avoid returning success for printing help so that automated build systems do not interpret "show the help"
                //As a successful build incase the build system is incorrectly passing arguments.
                return(ExitCodes.InvalidInputOrConfig);
            }
            var    inputs     = new List <string>();
            var    suppress   = new HashSet <int>();
            bool   quiet      = false;
            bool   verbose    = false;
            string report     = null;
            string extract    = null;
            var    revocation = RevocationChecking.None;
            var    ruleSet    = RuleSet.Modern;

            foreach (var parameter in parsedCommandLine)
            {
                if (parameter.Name == "in")
                {
                    if (string.IsNullOrWhiteSpace(parameter.Value))
                    {
                        Console.Error.WriteLine("A value is required for input.");
                        return(ExitCodes.InvalidInputOrConfig);
                    }
                    var filePattern = Path.GetFileName(parameter.Value);
                    //The value contains a pattern.
                    if (filePattern.Contains("*") || filePattern.Contains("?"))
                    {
                        var directory = Path.GetDirectoryName(parameter.Value);
                        if (Directory.Exists(directory))
                        {
                            var files = Directory.GetFiles(directory, filePattern, SearchOption.TopDirectoryOnly);
                            inputs.AddRange(files);
                        }
                    }
                    else
                    {
                        inputs.Add(parameter.Value);
                    }
                }
                else if (parameter.Name == "suppress")
                {
                    if (string.IsNullOrWhiteSpace(parameter.Value))
                    {
                        ShowInvalidSuppression();
                        return(ExitCodes.InvalidInputOrConfig);
                    }
                    foreach (var idString in parameter.Value.Split(',').Select(p => p.Trim()))
                    {
                        int id;
                        if (int.TryParse(idString, out id))
                        {
                            suppress.Add(id);
                        }
                        else
                        {
                            Console.Error.WriteLine($"{idString} is not a valid error ID.");
                            return(ExitCodes.InvalidInputOrConfig);
                        }
                    }
                }
                else if (parameter.Name == "q" || parameter.Name == "quiet")
                {
                    if (!string.IsNullOrWhiteSpace(parameter.Value))
                    {
                        Console.Error.WriteLine($"-{parameter.Name} does not expect a value.");
                        return(ExitCodes.InvalidInputOrConfig);
                    }
                    quiet = true;
                }
                else if (parameter.Name == "verbose")
                {
                    if (!string.IsNullOrWhiteSpace(parameter.Value))
                    {
                        Console.Error.WriteLine($"-{parameter.Name} does not expect a value.");
                        return(ExitCodes.InvalidInputOrConfig);
                    }
                    verbose = true;
                }

                else if (parameter.Name == "report")
                {
                    report = parameter.Value;
                }
                else if (parameter.Name == "extract")
                {
                    extract = parameter.Value;
                }
                else if (parameter.Name == "revocation")
                {
                    if (string.IsNullOrWhiteSpace(parameter.Value))
                    {
                        Console.Error.WriteLine($"-{parameter.Name} requires a value if specified.");
                        return(ExitCodes.InvalidInputOrConfig);
                    }
                    if (!Enum.TryParse(parameter.Value, true, out revocation))
                    {
                        Console.Error.WriteLine($"-{parameter.Value} is an unrecognized revocation mode.");
                        return(ExitCodes.InvalidInputOrConfig);
                    }
                }
                else if (parameter.Name == "ruleset")
                {
                    if (string.IsNullOrWhiteSpace(parameter.Value))
                    {
                        Console.Error.WriteLine($"-{parameter.Name} requires a value if specified.");
                        return(ExitCodes.InvalidInputOrConfig);
                    }
                    if (!Enum.TryParse(parameter.Value, true, out ruleSet) || parameter.Value.Equals("all", StringComparison.OrdinalIgnoreCase))
                    {
                        Console.Error.WriteLine($"-{parameter.Value} is an unrecognized ruleset.");
                        return(ExitCodes.InvalidInputOrConfig);
                    }
                }
                else
                {
                    Console.Error.WriteLine($"-{parameter.Name} is an unknown parameter.");
                    return(ExitCodes.InvalidInputOrConfig);
                }
            }
            if (inputs.Count == 0)
            {
                Console.Error.WriteLine("Input is expected. See -help for usage.");
                return(ExitCodes.InvalidInputOrConfig);
            }
            var configuration = new CheckConfiguration(inputs, report, quiet, suppress, verbose, revocation, extract, ruleSet);

            if (!ConfigurationValidator.ValidateAndPrint(configuration, Console.Error))
            {
                return(ExitCodes.InvalidInputOrConfig);
            }
            var collectors = new List <IRuleResultCollector>();

            if (!quiet)
            {
                collectors.Add(new StdOutRuleResultCollector());
            }
            if (!string.IsNullOrWhiteSpace(report))
            {
                collectors.Add(new XmlRuleResultCollector(report));
            }
            var result = ExitCodes.Success;

            foreach (var file in inputs)
            {
                var signatures = SignatureTreeInspector.Extract(file);
                if (CheckEngine.Instance.RunAllRules(file, signatures, collectors, configuration) != RuleEngineResult.AllPass)
                {
                    result = ExitCodes.ChecksFailed;
                }
            }
            collectors.ForEach(c => c.Flush());
            return(result);
        }
 private static IReadOnlyList <ICmsSignature> GetGraphForFile(string file)
 {
     return(SignatureTreeInspector.Extract(file));
 }
Ejemplo n.º 4
0
        static async Task Main(string[] args)
        {
            if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Console.Error.WriteLine("AuthenticodeLint is only supported on Windows.");
                //return ExitCodes.PlatformNotSupported;
            }
            var cli = Environment.CommandLine;
            List <CommandLineParameter> parsedCommandLine;

            try
            {
                var commandLine = CommandLineParser.LexCommandLine(cli).Skip(1);
                parsedCommandLine = CommandLineParser.CreateCommandLineParametersWithValues(commandLine).ToList();
            }
            catch (InvalidOperationException)
            {
                parsedCommandLine = null;
            }

            if (parsedCommandLine == null || parsedCommandLine.Count == 0 || parsedCommandLine.Any(cl => cl.Name == "help"))
            {
                ShowHelp();
                //Avoid returning success for printing help so that automated build systems do not interpret "show the help"
                //As a successful build incase the build system is incorrectly passing arguments.
                //return ExitCodes.InvalidInputOrConfig;
            }
            var    inputs     = new List <string>();
            var    suppress   = new HashSet <int>();
            bool   quiet      = false;
            bool   verbose    = false;
            string report     = null;
            string extract    = null;
            var    revocation = RevocationChecking.None;
            var    testSet    = TestSet.All;

            foreach (var parameter in parsedCommandLine)
            {
                if (parameter.Name == "vt")
                {
                    vt = true;
                }
                else if (parameter.Name == "in")
                {
                    if (string.IsNullOrWhiteSpace(parameter.Value))
                    {
                        Console.Error.WriteLine("A value is required for input.");
                        return;// ExitCodes.InvalidInputOrConfig;
                    }
                    var filePattern = Path.GetFileName(parameter.Value);
                    //The value contains a pattern.
                    if (filePattern.Contains("*") || filePattern.Contains("?"))
                    {
                        var directory = Path.GetDirectoryName(parameter.Value);
                        if (Directory.Exists(directory))
                        {
                            var files = Directory.GetFiles(directory, filePattern, SearchOption.TopDirectoryOnly);
                            inputs.AddRange(files);
                        }
                    }
                    else
                    {
                        inputs.Add(parameter.Value);
                    }
                }
                else if (parameter.Name == "validate")
                {
                    validate = parameter.Value;
                }
                else if (parameter.Name == "portal")
                {
                    portalName = parameter.Value;
                }
                else if (parameter.Name == "app")
                {
                    appName = parameter.Value;
                }
                else if (parameter.Name == "type")
                {
                    fileType = parameter.Value;
                }
                else if (parameter.Name == "number")
                {
                    fileNumber = Int32.Parse(parameter.Value);
                }
                else if (parameter.Name == "suppress")
                {
                    if (string.IsNullOrWhiteSpace(parameter.Value))
                    {
                        ShowInvalidSuppression();
                        return;// ExitCodes.InvalidInputOrConfig;
                    }
                    foreach (var idString in parameter.Value.Split(',').Select(p => p.Trim()))
                    {
                        int id;
                        if (int.TryParse(idString, out id))
                        {
                            suppress.Add(id);
                        }
                        else
                        {
                            Console.Error.WriteLine($"{idString} is not a valid error ID.");
                            return;// ExitCodes.InvalidInputOrConfig;
                        }
                    }
                }
                else if (parameter.Name == "q" || parameter.Name == "quiet")
                {
                    if (!string.IsNullOrWhiteSpace(parameter.Value))
                    {
                        Console.Error.WriteLine($"-{parameter.Name} does not expect a value.");
                        return;// ExitCodes.InvalidInputOrConfig;
                    }
                    quiet = true;
                }
                else if (parameter.Name == "verbose")
                {
                    if (!string.IsNullOrWhiteSpace(parameter.Value))
                    {
                        Console.Error.WriteLine($"-{parameter.Name} does not expect a value.");
                        return;// ExitCodes.InvalidInputOrConfig;
                    }
                    verbose = true;
                }

                else if (parameter.Name == "report")
                {
                    report = parameter.Value;
                }
                else if (parameter.Name == "extract")
                {
                    extract = parameter.Value;
                }
                else if (parameter.Name == "revocation")
                {
                    if (string.IsNullOrWhiteSpace(parameter.Value))
                    {
                        Console.Error.WriteLine($"-{parameter.Name} requires a value if specified.");
                        return;// ExitCodes.InvalidInputOrConfig;
                    }
                    if (!Enum.TryParse(parameter.Value, true, out revocation))
                    {
                        Console.Error.WriteLine($"-{parameter.Value} is an unrecognized revocation mode.");
                        return;// ExitCodes.InvalidInputOrConfig;
                    }
                }
                else if (parameter.Name == "testset")
                {
                    if (string.IsNullOrWhiteSpace(parameter.Value))
                    {
                        Console.Error.WriteLine($"-{parameter.Name} requires a value if specified.");
                        return;// ExitCodes.InvalidInputOrConfig;
                    }
                    if (!Enum.TryParse(parameter.Value, true, out testSet) || parameter.Value.Equals("all", StringComparison.OrdinalIgnoreCase))
                    {
                        Console.Error.WriteLine($"-{parameter.Value} is an unrecognized testset.");
                        return;// ExitCodes.InvalidInputOrConfig;
                    }
                }
                else
                {
                    Console.Error.WriteLine($"-{parameter.Name} is an unknown parameter.");
                    return;// ExitCodes.InvalidInputOrConfig;
                }
            }
            if (inputs.Count == 0)
            {
                Console.Error.WriteLine("Input is expected. See -help for usage.");
                return;// ExitCodes.InvalidInputOrConfig;
            }
            var configuration = new CheckConfiguration(inputs, report, quiet, suppress, verbose, revocation, extract, testSet);

            if (!ConfigurationValidator.ValidateAndPrint(configuration, Console.Error))
            {
                return;// ExitCodes.InvalidInputOrConfig;
            }
            var collectors = new List <ITestResultCollector>();

            if (!quiet)
            {
                collectors.Add(new StdOutTestResultCollector());
            }
            if (!string.IsNullOrWhiteSpace(report))
            {
                collectors.Add(new XmlTestResultCollector(report));
            }
            var result = ExitCodes.Success;

            foreach (var file in inputs)
            {
                filePath = Path.GetFullPath(file);
                if (!vt && validate.Equals(""))
                {
                    var signatures    = SignatureTreeInspector.Extract(file);
                    var verboseWriter = verbose ? new MemorySignatureLogger() : SignatureLogger.Null;
                    fileName = Path.GetFileName(file);
                    if (signatures.Count == 0)
                    {
                        DBConnect.InsertApplicationTable(appName, fileName, portalName, 0, fileType, fileNumber);
                        verboseWriter.LogMessage("File is not Authenticode signed.");
                    }
                    else
                    {
                        DBConnect.InsertApplicationTable(appName, fileName, portalName, 1, fileType, fileNumber);
                        signed = true;
                    }
                    if (CheckEngine.Instance.RunAllTests(file, signatures, collectors, configuration) != TestEngineResult.AllPass)
                    {
                        result = ExitCodes.ChecksFailed;
                    }
                }
                else
                {
                    fileName = Path.GetFileName(file);
                    filePath = Path.GetFullPath(file);
                    if (vt)
                    {
                        await VTChecker.GetScanReportForFile();
                    }

                    /*  else if (validate.Equals("signature"))
                     *    Validation.validate(fileName, signatureIndex, thumbprint);*/
                }
            }
            collectors.ForEach(c => c.Flush());
            return;// result;
        }