Esempio n. 1
0
        static void SignFilesWithSignTool(
            IReadOnlyCollection<string> files,
            string certificatePath,
            string certificatePassword,
            string display = "",
            string displayUrl = "")
        {
            if (!File.Exists(certificatePath))
                throw new Exception($"The code-signing certificate was not found at {certificatePath}");

            Log.Information("Signing {FilesCount} files using certificate at '{CertificatePath}'...",
                            files.Count,
                            certificatePath);

            TrySignTaskWithEachTimestampUrlUntilSuccess(url =>
                SignToolTasks.SignTool(_ =>
                   _.SetFileDigestAlgorithm(SignToolDigestAlgorithm.SHA256)
                    .SetFile(certificatePath)
                    .SetPassword(certificatePassword)
                    .SetDescription(display)
                    .SetUrl(displayUrl)
                    .SetRfc3161TimestampServerUrl(url)
                    .SetTimestampServerDigestAlgorithm(SignToolDigestAlgorithm.SHA256)
                    .AddFiles(files)));

            Log.Information("Finished signing {FilesCount} files", files.Count);
        }
Esempio n. 2
0
        public static void SignAssemblies(string password, params string[] fileNames)
        {
            SignToolSettings settings = new SignToolSettings()
                                        .SetFileDigestAlgorithm("SHA256")
                                        .SetFile(CertFileName)
                                        .SetFiles(fileNames)
                                        .SetPassword(password)
                                        .SetTimestampServerDigestAlgorithm("SHA256")
                                        .SetRfc3161TimestampServerUrl("http://timestamp.digicert.com");

            SignToolTasks.SignTool(settings);
        }
Esempio n. 3
0
    void SignWithSignTool(IEnumerable <string> files, string url)
    {
        Logger.Info("Signing files using signtool.");
        SignToolTasks.SignToolLogger = LogStdErrAsWarning;

        SignToolTasks.SignTool(_ => _
                               .SetFile(SigningCertificatePath)
                               .SetPassword(SigningCertificatePassword)
                               .SetFiles(files)
                               .SetProcessToolPath(RootDirectory / "certificates" / "signtool.exe")
                               .SetTimestampServerDigestAlgorithm("sha256")
                               .SetDescription("Octopus CLI")
                               .SetUrl("https://octopus.com")
                               .SetRfc3161TimestampServerUrl(url));
    }
Esempio n. 4
0
    private void SignFilesIfRequirementsMet(string filePath = null)
    {
        if (string.IsNullOrWhiteSpace(CodeSigningCertBase64))
        {
            Logger.Normal("Skipping file signing due to no certificate being provided");
            return;
        }

        var filesToSign = filePath == null
                          // If no file path is specified, we sign all *.exe and *.dll files
                          // in the output directory that have 'OpenProject' in their filename
       ? GlobFiles(OutputDirectory, "**/*OpenProject*.exe")
                          .Concat(GlobFiles(OutputDirectory, "**/*OpenProject*.dll"))
                          .Where(file => !_alreadySignedFiles.Contains(file))
                          .Distinct()
                          .ToList()
                          // In case a file path is given directly, we're using that
        : new[] { filePath }.ToList();

        filesToSign.ForEach(f => _alreadySignedFiles.Add(f));

        if (filesToSign.Any())
        {
            var certFilePath = OutputDirectory / $"{Guid.NewGuid()}-cert.pfx";
            var certContent  = Convert.FromBase64String(CodeSigningCertBase64);
            WriteAllBytes(certFilePath, certContent);

            Logger.Normal($"Signing files:{Environment.NewLine}{filesToSign.Aggregate((c, n) => c + Environment.NewLine + n)}");

            try
            {
                SignToolTasks
                .SignTool(c => c
                          .SetFileDigestAlgorithm("SHA256")
                          .SetFile(certFilePath)
                          .SetFiles(filesToSign)
                          .SetPassword(CodeSigningCertPassword)
                          .SetTimestampServerDigestAlgorithm("SHA256")
                          .SetRfc3161TimestampServerUrl("http://timestamp.digicert.com")
                          );
            }
            finally
            {
                DeleteFile(certFilePath);
            }
        }
    }
Esempio n. 5
0
    async Task SignFiles(IEnumerable <AbsolutePath> filesToSign)
    {
        // To create a pfx certificate for local testing, use powershell and run:
        // $outputLocation = "test_cert.pfx"
        // $cert = New-SelfSignedCertificate -DnsName sample.contoso.com -Type CodeSigning -CertStoreLocation Cert:\CurrentUser\My
        // $CertPassword = ConvertTo-SecureString -String "Passw0rd" -Force –AsPlainText
        // Export-PfxCertificate -Cert "cert:\CurrentUser\My\$($cert.Thumbprint)" -FilePath $outputLocation -Password $CertPassword

        var          tempFileName    = Path.GetTempFileName();
        const string timestampServer = "http://timestamp.digicert.com/";

        try
        {
            var(certPath, certPassword) = UseTestPfxCertificate
                                               ? (@"test_cert.pfx", "Passw0rd")
                                               : await GetSigningMaterial(tempFileName);

            Logger.Info("Signing material retrieved");

            var binaries = filesToSign
                           .Where(x => !x.ToString().EndsWith(".nupkg"))
                           .ToList();

            if (binaries.Any())
            {
                Logger.Info("Signing binaries...");
                binaries.ForEach(file => SignBinary(certPath, certPassword, file));
                Logger.Info("Binary signing complete");
            }

            var nupkgs = filesToSign
                         .Where(x => x.ToString().EndsWith(".nupkg"))
                         .ToList();

            if (nupkgs.Any())
            {
                Logger.Info("Signing NuGet packages...");
                nupkgs.ForEach(file => SignNuGet(certPath, certPassword, file));
                Logger.Info("NuGet signing complete");
            }
        }
        finally
        {
            File.Delete(tempFileName);
        }

        return;

        void SignBinary(string certPath, string certPassword, AbsolutePath binaryPath)
        {
            Logger.Info($"Signing {binaryPath}");

            SignToolTasks.SignTool(
                x => x
                .SetFiles(binaryPath)
                .SetFile(certPath)
                .SetPassword(certPassword)
                .SetTimestampServerUrl(timestampServer)
                );
        }

        void SignNuGet(string certPath, string certPassword, AbsolutePath binaryPath)
        {
            Logger.Info($"Signing {binaryPath}");

            // nuke doesn't expose the sign tool
            try
            {
                NuGetTasks.NuGet(
                    $"sign \"{binaryPath}\"" +
                    $" -CertificatePath {certPath}" +
                    $" -CertificatePassword {certPassword}" +
                    $" -Timestamper {timestampServer} -NonInteractive",
                    logOutput: false,
                    logInvocation: false,
                    logTimestamp: false); // don't print to std out/err
            }
            catch (Exception)
            {
                // Exception doesn't say anything useful generally and don't want to expose it if it does
                // so don't log it
                Logger.Error($"Failed to sign nuget package '{binaryPath}");
            }
        }

        async Task <(string CertificateFilePath, string Password)> GetSigningMaterial(string keyFile)
        {
            // Get the signing keys from SSM
            var pfxB64EncodedPart1 = await GetFileValueFromSsmUsingAmazonSdk("keygen.dd_win_agent_codesign.pfx_b64_0");

            var pfxB64EncodedPart2 = await GetFileValueFromSsmUsingAmazonSdk("keygen.dd_win_agent_codesign.pfx_b64_1");

            var pfxPassword = await GetFileValueFromSsmUsingAmazonSdk("keygen.dd_win_agent_codesign.password");

            var pfxB64Encoded = pfxB64EncodedPart1 + pfxB64EncodedPart2;

            Logger.Info($"Retrieved base64 encoded pfx. Length: {pfxB64Encoded.Length}");
            var pfxB64Decoded = Convert.FromBase64String(pfxB64Encoded);

            Logger.Info($"Writing key material to temporary file {keyFile}");
            File.WriteAllBytes(keyFile, pfxB64Decoded);

            Logger.Info("Verifying key material");
            var file = new X509Certificate2(keyFile, pfxPassword);

            file.Verify();

            return(CertificateFilePath : keyFile, Password : pfxPassword);