コード例 #1
0
        // Inspired from https://github.com/squaredup/bettersigntool/blob/master/bettersigntool/bettersigntool/SignCommand.cs

        async Task <bool> Sign(string file, SignArgs args)
        {
            var retry   = TimeSpan.FromSeconds(5);
            var attempt = 1;

            do
            {
                if (attempt > 1)
                {
                    logger.LogInformation($"Performing attempt #{attempt} of 3 attempts after {retry.TotalSeconds}s");
                    await Task.Delay(retry);
                }

                if (await RunSignTool(file, args))
                {
                    logger.LogInformation($"Signed successfully");
                    return(true);
                }

                attempt++;

                retry = TimeSpan.FromSeconds(Math.Pow(retry.TotalSeconds, 1.5));
            } while (attempt <= 3);

            logger.LogError($"Failed to sign. Attempts exceeded");

            throw new Exception($"Could not sign {file}");
        }
コード例 #2
0
        async Task SubmitInternal(string name, IList <string> files)
        {
            logger.LogInformation("Signing NuGetKeyVaultSignTool job {0} with {1} files", name, files.Count());

            var args = new SignArgs
            {
                HashAlgorithm     = HashAlgorithmName.SHA256,
                TimestampUrl      = keyVaultService.CertificateInfo.TimestampUrl,
                PublicCertificate = await keyVaultService.GetCertificateAsync(),
                Rsa = await keyVaultService.ToRSA()
            };

            try
            {
                var tasks = files.Select(file =>
                {
                    telemetryLogger.OnSignFile(file, signToolName);
                    return(Sign(file, args));
                });

                await Task.WhenAll(tasks);
            }
            finally
            {
                args.Rsa?.Dispose();
            }
        }
        async Task <bool> RunSignTool(string file, SignArgs args)
        {
            var startTime = DateTimeOffset.UtcNow;
            var stopwatch = Stopwatch.StartNew();


            logger.LogInformation("Signing using {fileName}", file);


            var success = false;

            try
            {
                success = await signCommand.SignAsync(
                    file,
                    file,
                    args.TimestampUrl,
                    args.HashAlgorithm,
                    args.HashAlgorithm,
                    true,
                    args.PublicCertificate,
                    args.Rsa
                    );
            }
            catch (Exception e)
            {
                logger.LogError(e, e.Message);
            }

            telemetryLogger.TrackSignToolDependency(signToolName, file, startTime, stopwatch.Elapsed, null, success ? 0 : -1);

            return(success);
        }
コード例 #4
0
 private TestContext(SignArgs args, TestDirectory directory, X509Certificate2 certificate, TestLogger logger)
 {
     Args        = args;
     Directory   = directory;
     Certificate = certificate;
     Runner      = new SignCommandRunner();
     Logger      = logger;
 }
コード例 #5
0
            internal static Test Create(X509Certificate2 certificate)
            {
                var directory       = TestDirectory.Create();
                var packageFilePath = CreatePackage(directory, "package.nupkg");
                var logger          = new TestLogger();

                var args = new SignArgs()
                {
                    Logger         = logger,
                    NonInteractive = true,
                    PackagePath    = packageFilePath
                };

                return(new Test(args, directory, certificate, logger));
            }
コード例 #6
0
            internal static async Task <TestContext> CreateAsync(X509Certificate2 certificate)
            {
                var directory       = TestDirectory.Create();
                var packageFilePath = await CreatePackageAsync(directory, "package.nupkg");

                var logger = new TestLogger();

                var args = new SignArgs()
                {
                    Logger         = logger,
                    NonInteractive = true,
                    PackagePaths   = new string[] { packageFilePath }
                };

                return(new TestContext(args, directory, certificate, logger));
            }
コード例 #7
0
        private void SignCommandArgs(Action <Mock <ISignCommandRunner>, CommandLineApplication, Func <LogLevel>, Func <SignArgs> > verify)
        {
            // Arrange
            var logLevel          = LogLevel.Information;
            var logger            = new TestCommandOutputLogger();
            var testApp           = new CommandLineApplication();
            var mockCommandRunner = new Mock <ISignCommandRunner>();

            SignArgs parsedArgs = null;

            mockCommandRunner
            .Setup(m => m.ExecuteCommandAsync(It.IsAny <SignArgs>()))
            .Callback <SignArgs>(x => parsedArgs = x)
            .Returns(Task.FromResult(0));

            testApp.Name = "dotnet nuget_test";
            SignCommand.Register(testApp,
                                 () => logger,
                                 ll => logLevel = ll,
                                 () => mockCommandRunner.Object);

            // Act & Assert
            verify(mockCommandRunner, testApp, () => logLevel, () => parsedArgs);
        }
コード例 #8
0
        internal static void Register(CommandLineApplication app,
                                      Func <ILogger> getLogger,
                                      Action <LogLevel> setLogLevel,
                                      Func <ISignCommandRunner> getCommandRunner)
        {
            app.Command(CommandName, signCmd =>
            {
                CommandArgument packagePaths = signCmd.Argument(
                    "<package-paths>",
                    Strings.SignCommandPackagePathDescription,
                    multipleValues: true);

                CommandOption outputDirectory = signCmd.Option(
                    "-o|--output",
                    Strings.SignCommandOutputDirectoryDescription,
                    CommandOptionType.SingleValue);

                CommandOption path = signCmd.Option(
                    "--certificate-path",
                    Strings.SignCommandCertificatePathDescription,
                    CommandOptionType.SingleValue);

                CommandOption store = signCmd.Option(
                    "--certificate-store-name",
                    Strings.SignCommandCertificateStoreNameDescription,
                    CommandOptionType.SingleValue);

                CommandOption location = signCmd.Option(
                    "--certificate-store-location",
                    Strings.SignCommandCertificateStoreLocationDescription,
                    CommandOptionType.SingleValue);

                CommandOption subject = signCmd.Option(
                    "--certificate-subject-name",
                    Strings.SignCommandCertificateSubjectNameDescription,
                    CommandOptionType.SingleValue);

                CommandOption fingerprint = signCmd.Option(
                    "--certificate-fingerprint",
                    Strings.SignCommandCertificateFingerprintDescription,
                    CommandOptionType.SingleValue);

                CommandOption password = signCmd.Option(
                    "--certificate-password",
                    Strings.SignCommandCertificatePasswordDescription,
                    CommandOptionType.SingleValue);

                CommandOption algorithm = signCmd.Option(
                    "--hash-algorithm",
                    Strings.SignCommandHashAlgorithmDescription,
                    CommandOptionType.SingleValue);

                CommandOption timestamper = signCmd.Option(
                    "--timestamper",
                    Strings.SignCommandTimestamperDescription,
                    CommandOptionType.SingleValue);

                CommandOption timestamperAlgorithm = signCmd.Option(
                    "--timestamp-hash-algorithm",
                    Strings.SignCommandTimestampHashAlgorithmDescription,
                    CommandOptionType.SingleValue);

                CommandOption overwrite = signCmd.Option(
                    "--overwrite",
                    Strings.SignCommandOverwriteDescription,
                    CommandOptionType.NoValue);

                CommandOption verbosity = signCmd.Option(
                    "-v|--verbosity",
                    Strings.Verbosity_Description,
                    CommandOptionType.SingleValue);

                signCmd.HelpOption(XPlatUtility.HelpOption);

                signCmd.Description = Strings.SignCommandDescription;

                signCmd.OnExecute(async() =>
                {
                    ILogger logger = getLogger();

                    ValidatePackagePaths(packagePaths);
                    WarnIfNoTimestamper(logger, timestamper);
                    ValidateCertificateInputs(path, fingerprint, subject, store, location);
                    ValidateAndCreateOutputDirectory(outputDirectory);

                    SigningSpecificationsV1 signingSpec = SigningSpecifications.V1;
                    StoreLocation storeLocation         = ValidateAndParseStoreLocation(location);
                    StoreName storeName                      = ValidateAndParseStoreName(store);
                    HashAlgorithmName hashAlgorithm          = CommandLineUtility.ParseAndValidateHashAlgorithm(algorithm.Value(), algorithm.LongName, signingSpec);
                    HashAlgorithmName timestampHashAlgorithm = CommandLineUtility.ParseAndValidateHashAlgorithm(timestamperAlgorithm.Value(), timestamperAlgorithm.LongName, signingSpec);

                    var args = new SignArgs()
                    {
                        PackagePaths             = packagePaths.Values,
                        OutputDirectory          = outputDirectory.Value(),
                        CertificatePath          = path.Value(),
                        CertificateStoreName     = storeName,
                        CertificateStoreLocation = storeLocation,
                        CertificateSubjectName   = subject.Value(),
                        CertificateFingerprint   = fingerprint.Value(),
                        CertificatePassword      = password.Value(),
                        SignatureHashAlgorithm   = hashAlgorithm,
                        Logger    = logger,
                        Overwrite = overwrite.HasValue(),
                        //The interactive option is not enabled at first, so the NonInteractive is always set to true. This is tracked by https://github.com/NuGet/Home/issues/10620
                        NonInteractive         = true,
                        Timestamper            = timestamper.Value(),
                        TimestampHashAlgorithm = timestampHashAlgorithm
                    };

                    setLogLevel(XPlatUtility.MSBuildVerbosityToNuGetLogLevel(verbosity.Value()));

                    ISignCommandRunner runner = getCommandRunner();
                    int result = await runner.ExecuteCommandAsync(args);
                    return(result);
                });
            });
        }