public void GetAllowListEntries_WithDuplicateEntries_ConflictingAllowUntrustedRoot_WarnsAndSetsToFalse()
        {
            // Arrange
            var config = @"
<configuration>
    <trustedSigners>
        <repository name=""repository1"" serviceIndex=""api.v3ServiceIndex.test/json"">
            <certificate fingerprint=""abc"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
            <certificate fingerprint=""def"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
            <certificate fingerprint=""abc"" hashAlgorithm=""SHA512"" allowUntrustedRoot=""false"" />
            <owners>nuget;randomOwner</owners>
        </repository>
        <author name=""author1"">
            <certificate fingerprint=""jkl"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
            <certificate fingerprint=""abc"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""true"" />
        </author>
    </trustedSigners>
</configuration>";

            var nugetConfigPath = "NuGet.Config";

            using (var mockBaseDirectory = TestDirectory.Create())
            {
                SettingsTestUtils.CreateConfigurationFile(nugetConfigPath, mockBaseDirectory, config);

                // Act and Assert
                var settings = new Settings(mockBaseDirectory);
                settings.Should().NotBeNull();

                var logger = new Mock <ILogger>();

                var entries = TrustedSignersProvider.GetAllowListEntries(settings, logger.Object);
                entries.Should().NotBeNull();
                entries.Count.Should().Be(4);

                logger.Verify(l =>
                              l.Log(It.Is <ILogMessage>(m =>
                                                        m.Level == LogLevel.Warning &&
                                                        m.Code == NuGetLogCode.NU3040)));

                var expectedEntries = new List <VerificationAllowListEntry>()
                {
                    new TrustedSignerAllowListEntry(VerificationTarget.Repository, SignaturePlacement.Any, "abc", HashAlgorithmName.SHA512, owners: new List <string>()
                    {
                        "nuget", "randomOwner"
                    }),
                    new TrustedSignerAllowListEntry(VerificationTarget.Author | VerificationTarget.Repository, SignaturePlacement.Any, "abc", HashAlgorithmName.SHA256, owners: new List <string>()
                    {
                        "nuget", "randomOwner"
                    }),
                    new TrustedSignerAllowListEntry(VerificationTarget.Repository, SignaturePlacement.Any, "def", HashAlgorithmName.SHA256, owners: new List <string>()
                    {
                        "nuget", "randomOwner"
                    }),
                    new TrustedSignerAllowListEntry(VerificationTarget.Author, SignaturePlacement.PrimarySignature, "jkl", HashAlgorithmName.SHA256),
                };

                entries.Should().BeEquivalentTo(expectedEntries);
            }
        }
Пример #2
0
        public void GetRestoreSettingsTask_FindConfigInProjectFolder()
        {
            // Verifies that we include any config file found in the project folder
            using (var machineWide = TestDirectory.CreateInTemp())
                using (var workingDir = TestDirectory.CreateInTemp())
                {
                    // Arrange
                    SettingsTestUtils.CreateConfigurationFile(Settings.DefaultSettingsFileName, machineWide, MachineWideSettingsConfig);
                    var machineWideSettings = new Lazy <IMachineWideSettings>(() => new TestMachineWideSettings(new Settings(machineWide, Settings.DefaultSettingsFileName, isMachineWide: true)));

                    var innerConfigFile = Path.Combine(workingDir, "sub", Settings.DefaultSettingsFileName);
                    var outerConfigFile = Path.Combine(workingDir, Settings.DefaultSettingsFileName);

                    var projectDirectory = Path.GetDirectoryName(innerConfigFile);
                    Directory.CreateDirectory(projectDirectory);

                    File.WriteAllText(innerConfigFile, InnerConfig);
                    File.WriteAllText(outerConfigFile, OuterConfig);

                    var settings = RestoreSettingsUtils.ReadSettings(null, projectDirectory, null, machineWideSettings);

                    var innerValue = SettingsUtility.GetValueForAddItem(settings, "SectionName", "inner-key");
                    var outerValue = SettingsUtility.GetValueForAddItem(settings, "SectionName", "outer-key");

                    // Assert
                    Assert.Equal("inner-value", innerValue);
                    Assert.Equal("outer-value", outerValue);
                    Assert.True(settings.GetConfigFilePaths().Contains(innerConfigFile));
                    Assert.True(settings.GetConfigFilePaths().Contains(outerConfigFile));
                }
        }
Пример #3
0
        public void DotnetTrust_ListAction_Succeeds()
        {
            using (SimpleTestPathContext pathContext = _msbuildFixture.CreateSimpleTestPathContext())
            {
                // Arrange
                var nugetConfigFileName = "NuGet.Config";
                var nugetConfigPath     = Path.Combine(pathContext.WorkingDirectory, nugetConfigFileName);

                var nugetConfigContent = $@"<?xml version=""1.0"" encoding=""utf-8""?>
                    <configuration>
                        <trustedSigners>
                            <author name=""signer"">
                                <certificate fingerprint=""abcdef"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
                            </author>
                        </trustedSigners>
                    </configuration>";

                var expectedAuthorContent = $@"Registered trusted signers:
                     1.   signer [author]
                          Certificate fingerprint(s):
                            SHA256 - abcdef
                    ";
                File.WriteAllText(nugetConfigPath, nugetConfigContent);

                //Act
                CommandRunnerResult result = _msbuildFixture.RunDotnet(
                    pathContext.WorkingDirectory,
                    $"nuget trust list --configfile {nugetConfigPath}");

                // Assert
                result.Success.Should().BeTrue();
                SettingsTestUtils.RemoveWhitespace(result.Output).Should().Contain(SettingsTestUtils.RemoveWhitespace(expectedAuthorContent));
            }
        }
Пример #4
0
        public async Task DotnetTrust_AuthorAction_RelativePathConfileFile_Succeeds(bool allowUntrustedRoot)
        {
            // Arrange
            var nugetConfigFileName = "NuGet.Config";
            var package             = new SimpleTestPackageContext();

            using (SimpleTestPathContext pathContext = _msbuildFixture.CreateSimpleTestPathContext())
                using (MemoryStream zipStream = await package.CreateAsStreamAsync())
                    using (TrustedTestCert <TestCertificate> trustedTestCert = SigningTestUtility.GenerateTrustedTestCertificate())
                    {
                        string certFingerprint   = SignatureTestUtility.GetFingerprint(trustedTestCert.Source.Cert, HashAlgorithmName.SHA256);
                        string signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync(trustedTestCert.Source.Cert, package, pathContext.PackageSource);

                        var config = $@"<?xml version=""1.0"" encoding=""utf-8""?>
                    <configuration>
                      <packageSources>
                        <!--To inherit the global NuGet package sources remove the <clear/> line below -->
                        <clear />
                        <add key=""NuGetSource"" value=""{pathContext.PackageSource}"" />
                       </packageSources>
                      <config>
                        <add key=""signaturevalidationmode"" value=""accept"" />
                      </config>
                      <trustedSigners>
                      </trustedSigners>
                    </configuration>";
                        SettingsTestUtils.CreateConfigurationFile(nugetConfigFileName, pathContext.WorkingDirectory, config);
                        var nugetConfigPath          = Path.Combine(pathContext.WorkingDirectory, nugetConfigFileName);
                        var allowUntrustedRootArg    = allowUntrustedRoot ? "--allow-untrusted-root" : string.Empty;
                        var allowUntruestedRootValue = allowUntrustedRoot ? "true" : "false";

                        // Act
                        CommandRunnerResult resultAdd = _msbuildFixture.RunDotnet(
                            pathContext.SolutionRoot,
                            $"nuget trust author nuget {signedPackagePath}  {allowUntrustedRootArg} --configfile ..{Path.DirectorySeparatorChar}{nugetConfigFileName}");

                        // Assert
                        resultAdd.Success.Should().BeTrue();
                        resultAdd.AllOutput.Should().Contain(string.Format(CultureInfo.CurrentCulture, _successfulAddTrustedSigner, "author", "nuget"));

                        string expectedResult = SettingsTestUtils.RemoveWhitespace($@"<?xml version=""1.0"" encoding=""utf-8""?>
                    <configuration>
                      <packageSources>
                        <!--To inherit the global NuGet package sources remove the < clear /> line below-->
                        <clear/>
                        <add key = ""NuGetSource"" value = ""{pathContext.PackageSource}""/>
                       </packageSources >
                      <config>
                        <add key = ""signaturevalidationmode"" value = ""accept""/>
                      </config>
                      < trustedSigners>
                            <author name = ""nuget"">
                                 <certificate fingerprint = ""{certFingerprint}"" hashAlgorithm = ""SHA256"" allowUntrustedRoot = ""{allowUntruestedRootValue}""/>
                            </author>
                      </trustedSigners>
                    </configuration>");

                        SettingsTestUtils.RemoveWhitespace(File.ReadAllText(nugetConfigPath)).Should().Be(expectedResult);
                    }
        }
        public void GetTrustedSigner_WithEmptyTrustedSignersSection_ReturnsEmptyList()
        {
            // Arrange
            var config = @"
<configuration>
    <trustedSigners>
    </trustedSigners>
</configuration>";

            var nugetConfigPath = "NuGet.Config";

            using (var mockBaseDirectory = TestDirectory.Create())
            {
                SettingsTestUtils.CreateConfigurationFile(nugetConfigPath, mockBaseDirectory, config);

                // Act and Assert
                var settings = new Settings(mockBaseDirectory);
                settings.Should().NotBeNull();

                var trustedSignerProvider = new TrustedSignersProvider(settings);

                var trustedSigners = trustedSignerProvider.GetTrustedSigners();
                trustedSigners.Should().NotBeNull();
                trustedSigners.Should().BeEmpty();
            }
        }
Пример #6
0
        public void TestConfigFileProbingDirectory()
        {
            // Arrange
            var parentConfig = @"<?xml version=""1.0"" encoding=""utf-8""?>
            <configuration>
                <fallbackPackageFolders>
                    <add key=""a"" value=""C:\Temp\a"" />
                </fallbackPackageFolders>
            </configuration>";

            var unreachableConfig = @"<?xml version=""1.0"" encoding=""utf-8""?>
            <configuration>
                <fallbackPackageFolders>
                    <add key=""b"" value=""C:\Temp\b"" />
                </fallbackPackageFolders>
            </configuration>";

            var baseConfig = @"<?xml version=""1.0"" encoding=""utf-8""?>
            <configuration>
                <packageSources>
                    <add key=""c"" value=""C:\Temp\c"" />
                </packageSources>
            </configuration>";

            var configName = "NuGet.Config";

            using (var machineWide = TestDirectory.CreateInTemp())
                using (var mockParentDirectory = TestDirectory.CreateInTemp())
                {
                    // Parent
                    //       Base
                    //            Probe Path
                    //       Unreachable
                    var basePath        = Path.Combine(mockParentDirectory, "base");
                    var unreachablePath = Path.Combine(mockParentDirectory, "unreachable");
                    var probePath       = Path.Combine(basePath, "probe");
                    Directory.CreateDirectory(basePath);
                    Directory.CreateDirectory(unreachablePath);
                    Directory.CreateDirectory(probePath);

                    SettingsTestUtils.CreateConfigurationFile(configName, mockParentDirectory, parentConfig);
                    SettingsTestUtils.CreateConfigurationFile(configName, basePath, baseConfig);
                    SettingsTestUtils.CreateConfigurationFile(configName, unreachablePath, unreachableConfig);

                    SettingsTestUtils.CreateConfigurationFile(configName, machineWide, MachineWideSettingsConfig);

                    var machineWideSettings = new Lazy <IMachineWideSettings>(() => new TestMachineWideSettings(new Settings(machineWide, configName, isMachineWide: true)));

                    // Test

                    var settings  = RestoreSettingsUtils.ReadSettings(null, probePath, null, machineWideSettings);
                    var filePaths = settings.GetConfigFilePaths();

                    Assert.Equal(4, filePaths.Count()); // base, parent, app data + machine wide
                    Assert.Contains(Path.Combine(basePath, configName), filePaths);
                    Assert.Contains(Path.Combine(mockParentDirectory, configName), filePaths);
                    Assert.DoesNotContain(Path.Combine(unreachablePath, configName), filePaths);
                }
        }
        public async Task TrustedSignersCommand_AddTrustedSigner_WithRepositoryCountersignedPackage_AddsItSuccesfullyToConfigAsync(bool allowUntrustedRoot, string owners)
        {
            // Arrange
            var nugetConfigFileName = "NuGet.Config";
            var config = @"<?xml version=""1.0"" encoding=""utf-8""?>
<configuration>
</configuration>";

            // Arrange
            var package = new SimpleTestPackageContext();

            using (var dir = TestDirectory.Create())
                using (var zipStream = await package.CreateAsStreamAsync())
                    using (var authorTrustedTestCert = SigningTestUtility.GenerateTrustedTestCertificate())
                        using (var repoTrustedTestCert = SigningTestUtility.GenerateTrustedTestCertificate())
                        {
                            var certFingerprint         = SignatureTestUtility.GetFingerprint(repoTrustedTestCert.Source.Cert, HashAlgorithmName.SHA256);
                            var repoServiceIndex        = "https://serviceindex.test/v3/index.json";
                            var authorSignedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync(authorTrustedTestCert.Source.Cert, package, dir);

                            var signedPackagePath = await SignedArchiveTestUtility.RepositorySignPackageAsync(repoTrustedTestCert.Source.Cert, authorSignedPackagePath, dir, new Uri(repoServiceIndex));

                            SettingsTestUtils.CreateConfigurationFile(nugetConfigFileName, dir, config);
                            var nugetConfigPath       = Path.Combine(dir, nugetConfigFileName);
                            var allowUntrustedRootArg = allowUntrustedRoot ? "-AllowUntrustedRoot" : string.Empty;
                            var ownersArgs            = string.Empty;
                            var expectedOwners        = string.Empty;

                            if (owners != null)
                            {
                                ownersArgs     = $"-Owners {owners}";
                                expectedOwners = $"<owners>{owners}</owners>";
                            }

                            // Act
                            var commandResult = CommandRunner.Run(
                                _nugetExePath,
                                dir,
                                $"trusted-signers add {signedPackagePath} -Name signer -Repository {allowUntrustedRootArg} {ownersArgs} -Config {nugetConfigPath}",
                                waitForExit: true);

                            // Assert
                            commandResult.Success.Should().BeTrue();
                            commandResult.AllOutput.Should().Contain(string.Format(CultureInfo.CurrentCulture, _successfulAddTrustedSigner, "repository", "signer"));

                            var expectedResult = SettingsTestUtils.RemoveWhitespace($@"<?xml version=""1.0"" encoding=""utf-8""?>
<configuration>
<trustedSigners>
    <repository name=""signer"" serviceIndex=""{repoServiceIndex}"">
        <certificate fingerprint=""{certFingerprint}"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""{allowUntrustedRoot.ToString().ToLower()}"" />
        {expectedOwners}
    </repository>
</trustedSigners>
</configuration>");

                            SettingsTestUtils.RemoveWhitespace(File.ReadAllText(nugetConfigPath)).Should().Be(expectedResult);
                        }
        }
Пример #8
0
        public void GetClientPolicy_ReadsAndParsesTrustedSigners()
        {
            // Arrange
            var config = @"
<configuration>
    <config>
        <add key=""signatureValidationMode"" value=""require"" />
    </config>
    <trustedSigners>
        <author name=""author1"">
            <certificate fingerprint=""abc"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
        </author>
        <repository name=""repository1"" serviceIndex=""https://v3serviceIndex.test/api/json"">
            <certificate fingerprint=""def"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""true"" />
        </repository>
    </trustedSigners>
</configuration>";

            var nugetConfigPath = "NuGet.Config";

            using (var mockBaseDirectory = TestDirectory.Create())
            {
                SettingsTestUtils.CreateConfigurationFile(nugetConfigPath, mockBaseDirectory, config);

                // Act and Assert
                var settings = new Settings(mockBaseDirectory);
                settings.Should().NotBeNull();

                var expectedAllowList = new List <VerificationAllowListEntry>()
                {
                    new TrustedSignerAllowListEntry(VerificationTarget.Author, SignaturePlacement.PrimarySignature, "abc", HashAlgorithmName.SHA256),
                    new TrustedSignerAllowListEntry(VerificationTarget.Repository, SignaturePlacement.Any, "def", HashAlgorithmName.SHA256, allowUntrustedRoot: true)
                };

                var clientPolicyContext = ClientPolicyContext.GetClientPolicy(settings, NullLogger.Instance);

                clientPolicyContext.Policy.Should().Be(SignatureValidationMode.Require);
                clientPolicyContext.AllowList.Count.Should().Be(2);
                clientPolicyContext.AllowList.Should().BeEquivalentTo(expectedAllowList);

                var verifierSettings = clientPolicyContext.VerifierSettings;

                verifierSettings.AllowUnsigned.Should().BeFalse();
                verifierSettings.AllowIllegal.Should().BeFalse();
                verifierSettings.AllowUntrusted.Should().BeFalse();
                verifierSettings.AllowIgnoreTimestamp.Should().BeTrue();
                verifierSettings.AllowMultipleTimestamps.Should().BeTrue();
                verifierSettings.AllowNoTimestamp.Should().BeTrue();
                verifierSettings.AllowUnknownRevocation.Should().BeTrue();
                verifierSettings.ReportUnknownRevocation.Should().BeTrue();
                verifierSettings.VerificationTarget.Should().Be(VerificationTarget.All);
                verifierSettings.SignaturePlacement.Should().Be(SignaturePlacement.Any);
                verifierSettings.RepositoryCountersignatureVerificationBehavior.Should().Be(SignatureVerificationBehavior.IfExistsAndIsNecessary);
                verifierSettings.RevocationMode.Should().Be(RevocationMode.Online);
            }
        }
Пример #9
0
        public async Task ClientPolicies_WithoutSignerInTrustedSignersList_WithMatchingOwnersAsync(SigningTestType signature, string validationMode, bool expectedResult, int expectedErrors, int expectedWarnings)
        {
            // Arrange
            using (var dir = TestDirectory.Create())
                using (var authorCertificate = new X509Certificate2(_trustedAuthorTestCert.Source.Cert))
                    using (var repoCertificate = new X509Certificate2(_trustedRepoTestCert.Source.Cert))
                    {
                        var authorCertificateFingerprintString = SignatureTestUtility.GetFingerprint(authorCertificate, HashAlgorithmName.SHA256);
                        var repoCertificateFingerprintString   = SignatureTestUtility.GetFingerprint(repoCertificate, HashAlgorithmName.SHA256);

                        var signedPackagePath = await CreateSignedPackageAsync(dir, signature, authorCertificate, repoCertificate);

                        var config = $@"
<configuration>
    <config>
        <add key=""signatureValidationMode"" value=""{validationMode}"" />
    </config>
    <trustedSigners>
        <repository name=""repo1"" serviceIndex=""https://api.v3serviceIndex.test/json"">
            <certificate fingerprint=""abc"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
            <owners>owner1</owners>
        </repository>
    </trustedSigners>
</configuration>";

                        var nugetConfigPath = "NuGet.Config";
                        SettingsTestUtils.CreateConfigurationFile(nugetConfigPath, dir, config);

                        // Act and Assert
                        var settings = new Settings(dir);

                        var verifierSettings = SignedPackageVerifierSettings.GetClientPolicy(settings, NullLogger.Instance);
                        var trustProviders   = new[]
                        {
                            new AllowListVerificationProvider()
                        };
                        var verifier = new PackageSignatureVerifier(trustProviders);

                        using (var packageReader = new PackageArchiveReader(signedPackagePath))
                        {
                            // Act
                            var result = await verifier.VerifySignaturesAsync(packageReader, verifierSettings, CancellationToken.None);

                            var resultsWithWarnings = result.Results.Where(r => r.GetWarningIssues().Any());
                            var resultsWithErrors   = result.Results.Where(r => r.GetErrorIssues().Any());
                            var totalWarningIssues  = resultsWithWarnings.SelectMany(r => r.GetWarningIssues());
                            var totalErrorIssues    = resultsWithErrors.SelectMany(r => r.GetErrorIssues());

                            // Assert
                            result.Valid.Should().Be(expectedResult);
                            totalWarningIssues.Count().Should().Be(expectedWarnings);
                            totalErrorIssues.Count().Should().Be(expectedErrors);
                        }
                    }
        }
        public void GetAllowListEntries_WithDuplicateFingerprints_DifferentHashAlgorithm_TakesThemAsDifferentEntries()
        {
            // Arrange
            var config = @"
<configuration>
    <trustedSigners>
        <repository name=""repository1"" serviceIndex=""api.v3ServiceIndex.test/json"">
            <certificate fingerprint=""abc"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
            <certificate fingerprint=""def"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
            <certificate fingerprint=""abc"" hashAlgorithm=""SHA512"" allowUntrustedRoot=""false"" />
            <owners>nuget;randomOwner</owners>
        </repository>
        <author name=""author1"">
            <certificate fingerprint=""jkl"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
            <certificate fingerprint=""abc"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
        </author>
    </trustedSigners>
</configuration>";

            var nugetConfigPath = "NuGet.Config";

            using (var mockBaseDirectory = TestDirectory.Create())
            {
                SettingsTestUtils.CreateConfigurationFile(nugetConfigPath, mockBaseDirectory, config);

                // Act and Assert
                var settings = new Settings(mockBaseDirectory);
                settings.Should().NotBeNull();

                var entries = TrustedSignersProvider.GetAllowListEntries(settings, NullLogger.Instance);
                entries.Should().NotBeNull();
                entries.Count.Should().Be(4);

                var expectedEntries = new List <VerificationAllowListEntry>()
                {
                    new TrustedSignerAllowListEntry(VerificationTarget.Repository, SignaturePlacement.Any, "abc", HashAlgorithmName.SHA512, owners: new List <string>()
                    {
                        "nuget", "randomOwner"
                    }),
                    new TrustedSignerAllowListEntry(VerificationTarget.Author | VerificationTarget.Repository, SignaturePlacement.Any, "abc", HashAlgorithmName.SHA256, owners: new List <string>()
                    {
                        "nuget", "randomOwner"
                    }),
                    new TrustedSignerAllowListEntry(VerificationTarget.Repository, SignaturePlacement.Any, "def", HashAlgorithmName.SHA256, owners: new List <string>()
                    {
                        "nuget", "randomOwner"
                    }),
                    new TrustedSignerAllowListEntry(VerificationTarget.Author, SignaturePlacement.PrimarySignature, "jkl", HashAlgorithmName.SHA256),
                };

                entries.Should().BeEquivalentTo(expectedEntries);
            }
        }
Пример #11
0
        public void AddOrUpdateTrustedSigner_WithNewTrustedSigner_AddsItSuccesfully()
        {
            // Arrange
            var config = @"
<configuration>
    <trustedSigners>
        <author name=""author1"">
            <certificate fingerprint=""abc"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
        </author>
        <author name=""author2"">
            <certificate fingerprint=""def"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
        </author>
        <repository name=""repo1"" serviceIndex=""https://serviceIndex.test/v3/api.json"">
            <certificate fingerprint=""ghi"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
        </repository>
    </trustedSigners>
</configuration>";

            var nugetConfigPath = "NuGet.Config";

            using (var mockBaseDirectory = TestDirectory.Create())
            {
                SettingsTestUtils.CreateConfigurationFile(nugetConfigPath, mockBaseDirectory, config);

                var expectedTrustedSigners = new List <TrustedSignerItem>()
                {
                    new AuthorItem("author1", new CertificateItem("abc", HashAlgorithmName.SHA256)),
                    new AuthorItem("author2", new CertificateItem("def", HashAlgorithmName.SHA256)),
                    new RepositoryItem("repo1", "https://serviceIndex.test/v3/api.json", new CertificateItem("ghi", HashAlgorithmName.SHA256)),
                    new AuthorItem("author3", new CertificateItem("jkl", HashAlgorithmName.SHA256)),
                };

                // Act and Assert
                var settings = new Settings(mockBaseDirectory);
                settings.Should().NotBeNull();

                var trustedSignerProvider = new TrustedSignersProvider(settings);

                trustedSignerProvider.AddOrUpdateTrustedSigner(new AuthorItem("author3", new CertificateItem("jkl", HashAlgorithmName.SHA256)));

                var trustedSigners = trustedSignerProvider.GetTrustedSigners();
                trustedSigners.Should().NotBeNull();
                trustedSigners.Count.Should().Be(4);
                trustedSigners.Should().BeEquivalentTo(
                    expectedTrustedSigners,
                    options => options
                    .Excluding(o => o.Path == "[0].Origin")
                    .Excluding(o => o.Path == "[1].Origin")
                    .Excluding(o => o.Path == "[2].Origin")
                    .Excluding(o => o.Path == "[3].Origin"));
            }
        }
Пример #12
0
        public void TestSolutionSettings()
        {
            // Arrange
            var subFolderConfig = @"<?xml version=""1.0"" encoding=""utf-8""?>
            <configuration>
                <fallbackPackageFolders>
                    <add key=""a"" value=""C:\Temp\a"" />
                </fallbackPackageFolders>
            </configuration>";

            var baseConfig = @"<?xml version=""1.0"" encoding=""utf-8""?>
            <configuration>
                <fallbackPackageFolders>
                    <add key=""b"" value=""C:\Temp\b"" />
                </fallbackPackageFolders>
                <packageSources>
                    <add key=""c"" value=""C:\Temp\c"" />
                </packageSources>
            </configuration>";



            var baseConfigPath = "NuGet.Config";

            using (var machineWide = TestDirectory.CreateInTemp())
                using (var mockBaseDirectory = TestDirectory.CreateInTemp())
                {
                    var subFolder = Path.Combine(mockBaseDirectory, "sub");
                    var solutionDirectoryConfig = Path.Combine(mockBaseDirectory, NuGetConstants.NuGetSolutionSettingsFolder);

                    SettingsTestUtils.CreateConfigurationFile(baseConfigPath, solutionDirectoryConfig, baseConfig);
                    SettingsTestUtils.CreateConfigurationFile(baseConfigPath, subFolder, subFolderConfig);
                    SettingsTestUtils.CreateConfigurationFile(baseConfigPath, machineWide, MachineWideSettingsConfig);
                    var machineWideSettings = new Lazy <IMachineWideSettings>(() => new TestMachineWideSettings(new Settings(machineWide, baseConfigPath, isMachineWide: true)));

                    // Test

                    var settings  = RestoreSettingsUtils.ReadSettings(mockBaseDirectory, mockBaseDirectory, null, machineWideSettings);
                    var filePaths = settings.GetConfigFilePaths();

                    Assert.Equal(3, filePaths.Count()); // Solution, app data + machine wide
                    Assert.True(filePaths.Contains(Path.Combine(solutionDirectoryConfig, baseConfigPath)));
                    Assert.True(filePaths.Contains(Path.Combine(machineWide, baseConfigPath)));

                    // Test
                    settings  = RestoreSettingsUtils.ReadSettings(mockBaseDirectory, mockBaseDirectory, Path.Combine(subFolder, baseConfigPath), machineWideSettings);
                    filePaths = settings.GetConfigFilePaths();

                    Assert.Equal(1, filePaths.Count());
                    Assert.True(filePaths.Contains(Path.Combine(subFolder, baseConfigPath)));
                }
        }
Пример #13
0
        public async Task DotnetTrust_CertificateFingerPrintAction_WithExistingSigner_AppendSucceeds(bool allowUntrustedRoot)
        {
            // Arrange
            var nugetConfigFileName = "NuGet.Config";
            var package             = new SimpleTestPackageContext();

            using (SimpleTestPathContext pathContext = _msbuildFixture.CreateSimpleTestPathContext())
                using (MemoryStream zipStream = await package.CreateAsStreamAsync())
                    using (TrustedTestCert <TestCertificate> trustedTestCert = SigningTestUtility.GenerateTrustedTestCertificate())
                    {
                        var certFingerprint   = SignatureTestUtility.GetFingerprint(trustedTestCert.Source.Cert, HashAlgorithmName.SHA256);
                        var repoServiceIndex  = "https://serviceindex.test/v3/index.json";
                        var signedPackagePath = await SignedArchiveTestUtility.RepositorySignPackageAsync(trustedTestCert.Source.Cert, package, pathContext.PackageSource, new Uri(repoServiceIndex));

                        var config = @"<?xml version=""1.0"" encoding=""utf-8""?>
<configuration>
    <trustedSigners>
        <author name=""MyCompanyCert"">
            <certificate fingerprint=""abcdefg"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
        </author>
    </trustedSigners>
</configuration>";

                        SettingsTestUtils.CreateConfigurationFile(nugetConfigFileName, pathContext.WorkingDirectory, config);
                        var nugetConfigPath          = Path.Combine(pathContext.WorkingDirectory, nugetConfigFileName);
                        var allowUntrustedRootArg    = allowUntrustedRoot ? "--allow-untrusted-root" : string.Empty;
                        var allowUntruestedRootValue = allowUntrustedRoot ? "true" : "false";
                        var authorName = "MyCompanyCert";

                        // Act
                        CommandRunnerResult resultAdd = _msbuildFixture.RunDotnet(
                            pathContext.SolutionRoot,
                            $"nuget trust certificate {authorName} {certFingerprint} {allowUntrustedRootArg}  --algorithm SHA256 --configfile {nugetConfigPath}");

                        // Assert
                        resultAdd.Success.Should().BeTrue();
                        resultAdd.AllOutput.Should().Contain(string.Format(CultureInfo.CurrentCulture, "Successfully updated the trusted signer '{0}'.", authorName));

                        string expectedResult = SettingsTestUtils.RemoveWhitespace($@"<?xml version=""1.0"" encoding=""utf-8""?>
                <configuration>
                    < trustedSigners>
                        <author name = ""{authorName}"">
                                < certificate fingerprint = ""abcdefg"" hashAlgorithm = ""SHA256"" allowUntrustedRoot = ""false""/>
                                < certificate fingerprint = ""{certFingerprint}"" hashAlgorithm = ""SHA256"" allowUntrustedRoot = ""{allowUntruestedRootValue}""/>
                        </author>
                    </trustedSigners>
                </configuration>");

                        SettingsTestUtils.RemoveWhitespace(File.ReadAllText(nugetConfigPath)).Should().Be(expectedResult);
                    }
        }
Пример #14
0
        public async Task DotnetTrust_RepositoryAction_Succeeds(bool allowUntrustedRoot, string owners)
        {
            // Arrange
            var nugetConfigFileName = "NuGet.Config";
            var package             = new SimpleTestPackageContext();

            using (SimpleTestPathContext pathContext = _msbuildFixture.CreateSimpleTestPathContext())
                using (MemoryStream zipStream = await package.CreateAsStreamAsync())
                    using (TrustedTestCert <TestCertificate> trustedTestCert = SigningTestUtility.GenerateTrustedTestCertificate())
                    {
                        var certFingerprint   = SignatureTestUtility.GetFingerprint(trustedTestCert.Source.Cert, HashAlgorithmName.SHA256);
                        var repoServiceIndex  = "https://serviceindex.test/v3/index.json";
                        var signedPackagePath = await SignedArchiveTestUtility.RepositorySignPackageAsync(trustedTestCert.Source.Cert, package, pathContext.PackageSource, new Uri(repoServiceIndex));

                        var config = $@"<?xml version=""1.0"" encoding=""utf-8""?>
                <configuration>
                </configuration>";
                        SettingsTestUtils.CreateConfigurationFile(nugetConfigFileName, pathContext.WorkingDirectory, config);
                        var nugetConfigPath          = Path.Combine(pathContext.WorkingDirectory, nugetConfigFileName);
                        var allowUntrustedRootArg    = allowUntrustedRoot ? "--allow-untrusted-root" : string.Empty;
                        var allowUntruestedRootValue = allowUntrustedRoot ? "true" : "false";
                        var ownersArgs     = string.Empty;
                        var expectedOwners = string.Empty;

                        if (owners != null)
                        {
                            ownersArgs     = $"--owners {owners}";
                            expectedOwners = $"<owners>{owners}</owners>";
                        }

                        // Act
                        CommandRunnerResult resultAdd = _msbuildFixture.RunDotnet(
                            pathContext.SolutionRoot,
                            $"nuget trust repository nuget {signedPackagePath}  {allowUntrustedRootArg} {ownersArgs} --configfile {nugetConfigPath}");

                        // Assert
                        resultAdd.Success.Should().BeTrue();
                        resultAdd.AllOutput.Should().Contain(string.Format(CultureInfo.CurrentCulture, _successfulAddTrustedSigner, "repository", "nuget"));

                        string expectedResult = SettingsTestUtils.RemoveWhitespace($@"<?xml version=""1.0"" encoding=""utf-8""?>
                <configuration>
                    < trustedSigners>
                        <repository name = ""nuget"" serviceIndex=""https://serviceindex.test/v3/index.json"">
                                < certificate fingerprint = ""{certFingerprint}"" hashAlgorithm = ""SHA256"" allowUntrustedRoot = ""{allowUntruestedRootValue}""/>{expectedOwners}
                        </repository>
                    </trustedSigners>
                </configuration>");

                        SettingsTestUtils.RemoveWhitespace(File.ReadAllText(nugetConfigPath)).Should().Be(expectedResult);
                    }
        }
        public void GetTrustedSigner_WithItemsDifferentThanTrustedSigners_IgnoresThemAndOnlyReturnsTrustedSigners()
        {
            // Arrange
            var config = @"
<configuration>
    <trustedSigners>
        <add key=""oneKey"" value=""val"" />
        <author name=""author1"">
            <certificate fingerprint=""abc"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
        </author>
        <author name=""author2"">
            <certificate fingerprint=""def"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
        </author>
        <certificate fingerprint=""ghi"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
        <repository name=""repo1"" serviceIndex=""https://serviceIndex.test/v3/api.json"">
            <certificate fingerprint=""ghi"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
        </repository>
        <add key=""otherKey"" value=""val"" />
    </trustedSigners>
</configuration>";

            var nugetConfigPath = "NuGet.Config";

            using (var mockBaseDirectory = TestDirectory.Create())
            {
                SettingsTestUtils.CreateConfigurationFile(nugetConfigPath, mockBaseDirectory, config);

                var expectedTrustedSigners = new List <TrustedSignerItem>()
                {
                    new AuthorItem("author1", new CertificateItem("abc", HashAlgorithmName.SHA256)),
                    new AuthorItem("author2", new CertificateItem("def", HashAlgorithmName.SHA256)),
                    new RepositoryItem("repo1", "https://serviceIndex.test/v3/api.json", new CertificateItem("ghi", HashAlgorithmName.SHA256))
                };

                // Act and Assert
                var settings = new Settings(mockBaseDirectory);
                settings.Should().NotBeNull();

                var trustedSignerProvider = new TrustedSignersProvider(settings);

                var trustedSigners = trustedSignerProvider.GetTrustedSigners();
                trustedSigners.Should().NotBeNull();
                trustedSigners.Count.Should().Be(3);
                trustedSigners.Should().BeEquivalentTo(
                    expectedTrustedSigners,
                    options => options
                    .Excluding(o => o.SelectedMemberPath == "[0].Origin")
                    .Excluding(o => o.SelectedMemberPath == "[1].Origin")
                    .Excluding(o => o.SelectedMemberPath == "[2].Origin"));
            }
        }
Пример #16
0
        public async Task ClientPolicies_WithNoTrustedSignersListAsync(SigningTestType signature, string validationMode, bool expectedResult, int expectedErrors)
        {
            // Arrange
            using (var dir = TestDirectory.Create())
                using (var authorCertificate = new X509Certificate2(_trustedAuthorTestCert.Source.Cert))
                    using (var repoCertificate = new X509Certificate2(_trustedRepoTestCert.Source.Cert))
                    {
                        var authorCertificateFingerprintString = SignatureTestUtility.GetFingerprint(authorCertificate, HashAlgorithmName.SHA256);
                        var repoCertificateFingerprintString   = SignatureTestUtility.GetFingerprint(repoCertificate, HashAlgorithmName.SHA256);
                        var signedPackagePath = await CreateSignedPackageAsync(dir, signature, authorCertificate, repoCertificate);

                        var config = $@"
<configuration>
    <config>
        <add key=""signatureValidationMode"" value=""{validationMode}"" />
    </config>
</configuration>";

                        var nugetConfigPath = "NuGet.Config";
                        SettingsTestUtils.CreateConfigurationFile(nugetConfigPath, dir, config);

                        // Act and Assert
                        var settings = new Settings(dir);

                        var clientPolicyContext = ClientPolicyContext.GetClientPolicy(settings, NullLogger.Instance);
                        var trustProviders      = new[]
                        {
                            new AllowListVerificationProvider(clientPolicyContext.AllowList, requireNonEmptyAllowList: clientPolicyContext.Policy == SignatureValidationMode.Require)
                        };
                        var verifier = new PackageSignatureVerifier(trustProviders);

                        using (var packageReader = new PackageArchiveReader(signedPackagePath))
                        {
                            // Act
                            var result = await verifier.VerifySignaturesAsync(packageReader, clientPolicyContext.VerifierSettings, CancellationToken.None);

                            var resultsWithWarnings = result.Results.Where(r => r.GetWarningIssues().Any());
                            var resultsWithErrors   = result.Results.Where(r => r.GetErrorIssues().Any());
                            var totalWarningIssues  = resultsWithWarnings.SelectMany(r => r.GetWarningIssues());
                            var totalErrorIssues    = resultsWithErrors.SelectMany(r => r.GetErrorIssues());

                            // Assert
                            result.IsValid.Should().Be(expectedResult);
                            totalWarningIssues.Count().Should().Be(0);
                            totalErrorIssues.Count().Should().Be(expectedErrors);
                        }
                    }
        }
        public async Task TrustedSignersCommand_AddTrustedSigner_WithAuthorSignedPackage_AddsItSuccesfullyToConfigAsync(bool allowUntrustedRoot)
        {
            // Arrange
            var nugetConfigFileName = "NuGet.Config";
            var config = @"<?xml version=""1.0"" encoding=""utf-8""?>
<configuration>
</configuration>";

            // Arrange
            var package = new SimpleTestPackageContext();

            using (var dir = TestDirectory.Create())
                using (var zipStream = await package.CreateAsStreamAsync())
                    using (var trustedTestCert = SigningTestUtility.GenerateTrustedTestCertificate())
                    {
                        var certFingerprint   = SignatureTestUtility.GetFingerprint(trustedTestCert.Source.Cert, HashAlgorithmName.SHA256);
                        var signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync(trustedTestCert.Source.Cert, package, dir);

                        SettingsTestUtils.CreateConfigurationFile(nugetConfigFileName, dir, config);
                        var nugetConfigPath       = Path.Combine(dir, nugetConfigFileName);
                        var allowUntrustedRootArg = allowUntrustedRoot ? "-AllowUntrustedRoot" : string.Empty;

                        // Act
                        var commandResult = CommandRunner.Run(
                            _nugetExePath,
                            dir,
                            $"trusted-signers add {signedPackagePath} -Name signer -Author {allowUntrustedRootArg} -Config {nugetConfigPath}",
                            waitForExit: true);

                        // Assert
                        commandResult.Success.Should().BeTrue();
                        commandResult.AllOutput.Should().Contain(string.Format(CultureInfo.CurrentCulture, _successfulAddTrustedSigner, "author", "signer"));

                        var expectedResult = SettingsTestUtils.RemoveWhitespace($@"<?xml version=""1.0"" encoding=""utf-8""?>
<configuration>
<trustedSigners>
    <author name=""signer"">
        <certificate fingerprint=""{certFingerprint}"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""{allowUntrustedRoot.ToString().ToLower()}"" />
    </author>
</trustedSigners>
</configuration>");

                        SettingsTestUtils.RemoveWhitespace(File.ReadAllText(nugetConfigPath)).Should().Be(expectedResult);
                    }
        }
        public void Remove_IgnoresAnyUnexistantTrustedSigner()
        {
            // Arrange
            var config = @"
<configuration>
    <trustedSigners>
        <author name=""author1"">
            <certificate fingerprint=""abc"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
        </author>
        <author name=""author2"">
            <certificate fingerprint=""def"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
        </author>
        <repository name=""repo1"" serviceIndex=""https://serviceIndex.test/v3/api.json"">
            <certificate fingerprint=""ghi"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
        </repository>
    </trustedSigners>
</configuration>";

            var nugetConfigPath = "NuGet.Config";

            using (var mockBaseDirectory = TestDirectory.Create())
            {
                SettingsTestUtils.CreateConfigurationFile(nugetConfigPath, mockBaseDirectory, config);

                var expectedTrustedSigners = new List <TrustedSignerItem>()
                {
                    new AuthorItem("author2", new CertificateItem("def", HashAlgorithmName.SHA256)),
                    new RepositoryItem("repo1", "https://serviceIndex.test/v3/api.json", new CertificateItem("ghi", HashAlgorithmName.SHA256))
                };

                // Act and Assert
                var settings = new Settings(mockBaseDirectory);
                settings.Should().NotBeNull();

                var trustedSignerProvider = new TrustedSignersProvider(settings);

                var trustedSigners = trustedSignerProvider.GetTrustedSigners();
                trustedSignerProvider.Remove(new[] { trustedSigners.First(), new AuthorItem("DontExist", new CertificateItem("abc", HashAlgorithmName.SHA256)) });

                trustedSigners = trustedSignerProvider.GetTrustedSigners();
                trustedSigners.Should().NotBeNull();
                trustedSigners.Count.Should().Be(2);
                trustedSigners.Should().BeEquivalentTo(expectedTrustedSigners);
            }
        }
        public void TrustedSignersCommand_AddTrustedSigner_WithExistingSigner_UpdatesItSuccesfullyInConfig(bool allowUntrustedRoot)
        {
            // Arrange
            var nugetConfigFileName = "NuGet.Config";
            var config = @"<?xml version=""1.0"" encoding=""utf-8""?>
<configuration>
    <trustedSigners>
        <author name=""signer"">
            <certificate fingerprint=""abcdefg"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
        </author>
    </trustedSigners>
</configuration>";

            // Arrange
            using (var dir = TestDirectory.Create())
            {
                SettingsTestUtils.CreateConfigurationFile(nugetConfigFileName, dir, config);
                var nugetConfigPath       = Path.Combine(dir, nugetConfigFileName);
                var allowUntrustedRootArg = allowUntrustedRoot ? "-AllowUntrustedRoot" : string.Empty;

                // Act
                var commandResult = CommandRunner.Run(
                    _nugetExePath,
                    dir,
                    $"trusted-signers add -Name signer -CertificateFingerprint hijklmn -FingerprintAlgorithm SHA256 {allowUntrustedRootArg} -Config {nugetConfigPath}",
                    waitForExit: true);

                // Assert
                commandResult.Success.Should().BeTrue();
                commandResult.AllOutput.Should().Contain(string.Format(CultureInfo.CurrentCulture, _successfulActionTrustedSigner, "updated", "signer", "signer"));

                var expectedResult = SettingsTestUtils.RemoveWhitespace($@"<?xml version=""1.0"" encoding=""utf-8""?>
<configuration>
    <trustedSigners>
        <author name=""signer"">
            <certificate fingerprint=""abcdefg"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
            <certificate fingerprint=""hijklmn"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""{allowUntrustedRoot.ToString().ToLower()}"" />
        </author>
    </trustedSigners>
</configuration>");

                SettingsTestUtils.RemoveWhitespace(File.ReadAllText(nugetConfigPath)).Should().Be(expectedResult);
            }
        }
        public void GetAllowListEntries_TrustedRepository_WithMultipleCertificates_ParsedCorrectly()
        {
            // Arrange
            var config = @"
<configuration>
    <trustedSigners>
        <repository name=""repository1"" serviceIndex=""api.v3ServiceIndex.test/json"">
            <certificate fingerprint=""abc"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
            <certificate fingerprint=""def"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
            <certificate fingerprint=""ghi"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
        </repository>
        <repository name=""repository2"" serviceIndex=""api.v3ServiceIndex.test/json"">
            <certificate fingerprint=""jkl"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
            <certificate fingerprint=""mno"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
        </repository>
    </trustedSigners>
</configuration>";

            var nugetConfigPath = "NuGet.Config";

            using (var mockBaseDirectory = TestDirectory.Create())
            {
                SettingsTestUtils.CreateConfigurationFile(nugetConfigPath, mockBaseDirectory, config);

                // Act and Assert
                var settings = new Settings(mockBaseDirectory);
                settings.Should().NotBeNull();

                var entries = TrustedSignersProvider.GetAllowListEntries(settings, NullLogger.Instance);
                entries.Should().NotBeNull();
                entries.Count.Should().Be(5);

                var expectedEntries = new List <VerificationAllowListEntry>()
                {
                    new TrustedSignerAllowListEntry(VerificationTarget.Repository, SignaturePlacement.Any, "abc", HashAlgorithmName.SHA256),
                    new TrustedSignerAllowListEntry(VerificationTarget.Repository, SignaturePlacement.Any, "def", HashAlgorithmName.SHA256),
                    new TrustedSignerAllowListEntry(VerificationTarget.Repository, SignaturePlacement.Any, "ghi", HashAlgorithmName.SHA256),
                    new TrustedSignerAllowListEntry(VerificationTarget.Repository, SignaturePlacement.Any, "jkl", HashAlgorithmName.SHA256),
                    new TrustedSignerAllowListEntry(VerificationTarget.Repository, SignaturePlacement.Any, "mno", HashAlgorithmName.SHA256)
                };

                entries.Should().BeEquivalentTo(expectedEntries);
            }
        }
Пример #21
0
        public async Task DotnetTrust_CertificateFingerPrintAction_TryAddSameFingerPrint_Fails(bool allowUntrustedRoot)
        {
            // Arrange
            var nugetConfigFileName = "NuGet.Config";
            var package             = new SimpleTestPackageContext();

            using (SimpleTestPathContext pathContext = _msbuildFixture.CreateSimpleTestPathContext())
                using (MemoryStream zipStream = await package.CreateAsStreamAsync())
                    using (TrustedTestCert <TestCertificate> trustedTestCert = SigningTestUtility.GenerateTrustedTestCertificate())
                    {
                        var certFingerprint   = SignatureTestUtility.GetFingerprint(trustedTestCert.Source.Cert, HashAlgorithmName.SHA256);
                        var repoServiceIndex  = "https://serviceindex.test/v3/index.json";
                        var signedPackagePath = await SignedArchiveTestUtility.RepositorySignPackageAsync(trustedTestCert.Source.Cert, package, pathContext.PackageSource, new Uri(repoServiceIndex));

                        var config = $@"<?xml version=""1.0"" encoding=""utf-8""?>
                <configuration>
                </configuration>";
                        SettingsTestUtils.CreateConfigurationFile(nugetConfigFileName, pathContext.WorkingDirectory, config);
                        var nugetConfigPath          = Path.Combine(pathContext.WorkingDirectory, nugetConfigFileName);
                        var allowUntrustedRootArg    = allowUntrustedRoot ? "--allow-untrusted-root" : string.Empty;
                        var allowUntruestedRootValue = allowUntrustedRoot ? "true" : "false";
                        var authorName = "MyCompanyCert";

                        // Act
                        CommandRunnerResult result = _msbuildFixture.RunDotnet(
                            pathContext.SolutionRoot,
                            $"nuget trust certificate {authorName} {certFingerprint} {allowUntrustedRootArg}  --algorithm SHA256 --configfile {nugetConfigPath}");

                        // Assert
                        result.Success.Should().BeTrue();
                        result.AllOutput.Should().Contain(string.Format(CultureInfo.CurrentCulture, _successfulAddTrustedSigner, "author", authorName));

                        // Try to add same certificate fingerprint should fail
                        result = _msbuildFixture.RunDotnet(
                            pathContext.SolutionRoot,
                            $"nuget trust certificate {authorName} {certFingerprint} {allowUntrustedRootArg}  --algorithm SHA256 --configfile {nugetConfigPath}", ignoreExitCode: true);

                        // Main assert
                        result.Success.Should().BeFalse();
                        result.AllOutput.Should().Contain("The certificate finger you're trying to add is already in the certificate fingerprint list");
                        result.AllOutput.Should().NotContain("--help");
                    }
        }
Пример #22
0
        public async Task DotnetTrust_RemoveAction_Succeeds()
        {
            // Arrange
            var nugetConfigFileName = "NuGet.Config";
            var package             = new SimpleTestPackageContext();

            using (SimpleTestPathContext pathContext = _msbuildFixture.CreateSimpleTestPathContext())
                using (MemoryStream zipStream = await package.CreateAsStreamAsync())
                    using (TrustedTestCert <TestCertificate> trustedTestCert = SigningTestUtility.GenerateTrustedTestCertificate())
                    {
                        var certFingerprint   = SignatureTestUtility.GetFingerprint(trustedTestCert.Source.Cert, HashAlgorithmName.SHA256);
                        var repoServiceIndex  = "https://serviceindex.test/v3/index.json";
                        var signedPackagePath = await SignedArchiveTestUtility.RepositorySignPackageAsync(trustedTestCert.Source.Cert, package, pathContext.PackageSource, new Uri(repoServiceIndex));

                        var repositoryName = "nuget";

                        var config = $@"<?xml version=""1.0"" encoding=""utf-8""?>
                <configuration>
                    <trustedSigners>
                        <repository name = ""{repositoryName}"" serviceIndex=""https://serviceindex.test/v3/index.json"">
                            <certificate fingerprint=""abcdef"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false""/>
                        </repository>
                    </trustedSigners>
                </configuration>";
                        SettingsTestUtils.CreateConfigurationFile(nugetConfigFileName, pathContext.WorkingDirectory, config);
                        var nugetConfigPath = Path.Combine(pathContext.WorkingDirectory, nugetConfigFileName);

                        // Act
                        CommandRunnerResult resultSync = _msbuildFixture.RunDotnet(
                            pathContext.SolutionRoot,
                            $"nuget trust remove {repositoryName} --configfile {nugetConfigPath}");

                        // Assert
                        resultSync.Success.Should().BeTrue();
                        resultSync.AllOutput.Should().Contain(string.Format(CultureInfo.CurrentCulture, _successfulRemoveTrustedSigner, repositoryName));

                        string expectedResult = SettingsTestUtils.RemoveWhitespace($@"<?xml version=""1.0"" encoding=""utf-8""?>
                <configuration>
                </configuration>");

                        SettingsTestUtils.RemoveWhitespace(File.ReadAllText(nugetConfigPath)).Should().Be(expectedResult);
                    }
        }
Пример #23
0
        public void GetClientPolicy_AcceptMode_ReadsClientPolicyCorrectly()
        {
            // Arrange
            var config = @"
<configuration>
    <config>
        <add key=""signatureValidationMode"" value=""accept"" />
    </config>
</configuration>";

            var nugetConfigPath = "NuGet.Config";

            using (var mockBaseDirectory = TestDirectory.Create())
            {
                SettingsTestUtils.CreateConfigurationFile(nugetConfigPath, mockBaseDirectory, config);

                // Act and Assert
                var settings = new Settings(mockBaseDirectory);
                settings.Should().NotBeNull();

                var clientPolicyContext = ClientPolicyContext.GetClientPolicy(settings, NullLogger.Instance);

                clientPolicyContext.Policy.Should().Be(SignatureValidationMode.Accept);
                clientPolicyContext.AllowList.Should().BeEmpty();

                var verifierSettings = clientPolicyContext.VerifierSettings;

                verifierSettings.AllowUnsigned.Should().BeTrue();
                verifierSettings.AllowIllegal.Should().BeTrue();
                verifierSettings.AllowUntrusted.Should().BeTrue();
                verifierSettings.AllowIgnoreTimestamp.Should().BeTrue();
                verifierSettings.AllowMultipleTimestamps.Should().BeTrue();
                verifierSettings.AllowNoTimestamp.Should().BeTrue();
                verifierSettings.AllowUnknownRevocation.Should().BeTrue();
                verifierSettings.ReportUnknownRevocation.Should().BeFalse();
                verifierSettings.VerificationTarget.Should().Be(VerificationTarget.All);
                verifierSettings.SignaturePlacement.Should().Be(SignaturePlacement.Any);
                verifierSettings.RepositoryCountersignatureVerificationBehavior.Should().Be(SignatureVerificationBehavior.IfExistsAndIsNecessary);
                verifierSettings.RevocationMode.Should().Be(RevocationMode.Online);
            }
        }
Пример #24
0
        public async Task DotnetTrust_AuthorAction_TryAddSameAuthor_Fails(bool allowUntrustedRoot)
        {
            // Arrange
            var nugetConfigFileName = "NuGet.Config";
            var package             = new SimpleTestPackageContext();

            using (SimpleTestPathContext pathContext = _msbuildFixture.CreateSimpleTestPathContext())
                using (MemoryStream zipStream = await package.CreateAsStreamAsync())
                    using (TrustedTestCert <TestCertificate> trustedTestCert = SigningTestUtility.GenerateTrustedTestCertificate())
                    {
                        string certFingerprint   = SignatureTestUtility.GetFingerprint(trustedTestCert.Source.Cert, HashAlgorithmName.SHA256);
                        string signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync(trustedTestCert.Source.Cert, package, pathContext.PackageSource);

                        var config = $@"<?xml version=""1.0"" encoding=""utf-8""?>
                <configuration>
                </configuration>";
                        SettingsTestUtils.CreateConfigurationFile(nugetConfigFileName, pathContext.WorkingDirectory, config);
                        var nugetConfigPath          = Path.Combine(pathContext.WorkingDirectory, nugetConfigFileName);
                        var allowUntrustedRootArg    = allowUntrustedRoot ? "--allow-untrusted-root" : string.Empty;
                        var allowUntruestedRootValue = allowUntrustedRoot ? "true" : "false";

                        // Act
                        CommandRunnerResult resultAdd = _msbuildFixture.RunDotnet(
                            pathContext.SolutionRoot,
                            $"nuget trust author nuget {signedPackagePath}  {allowUntrustedRootArg} --configfile {nugetConfigPath}");

                        // Assert
                        resultAdd.Success.Should().BeTrue();

                        // Try to add same author again.
                        resultAdd = _msbuildFixture.RunDotnet(
                            pathContext.SolutionRoot,
                            $"nuget trust author nuget {signedPackagePath}  {allowUntrustedRootArg} --configfile {nugetConfigPath}", ignoreExitCode: true);

                        // Main assert
                        resultAdd.Success.Should().BeFalse();
                        resultAdd.AllOutput.Should().Contain("error: A trusted signer 'nuget' already exists.");
                        resultAdd.AllOutput.Should().NotContain("--help");
                    }
        }
Пример #25
0
        public async Task TrustedSignersCommand_AddTrustedSigner_WithAuthorSignedPackage_AddsMultipleFilesThrows(bool allowUntrustedRoot)
        {
            // Arrange
            var nugetConfigFileName = "NuGet.Config";
            var config = @"<?xml version=""1.0"" encoding=""utf-8""?>
<configuration>
</configuration>";

            // Arrange
            var nupkgA = new SimpleTestPackageContext("A", "1.0.0");
            var nupkgB = new SimpleTestPackageContext("B", "1.0.0");

            using (var dir = TestDirectory.Create())
                using (var zipStream = await nupkgA.CreateAsStreamAsync())
                    using (var trustedTestCert = SigningTestUtility.GenerateTrustedTestCertificate())
                    {
                        var certFingerprint    = SignatureTestUtility.GetFingerprint(trustedTestCert.Source.Cert, HashAlgorithmName.SHA256);
                        var signedPackagePathA = await SignedArchiveTestUtility.AuthorSignPackageAsync(trustedTestCert.Source.Cert, nupkgA, dir);

                        var signedPackagePathB = await SignedArchiveTestUtility.AuthorSignPackageAsync(trustedTestCert.Source.Cert, nupkgB, dir);

                        SettingsTestUtils.CreateConfigurationFile(nugetConfigFileName, dir, config);
                        var nugetConfigPath       = Path.Combine(dir, nugetConfigFileName);
                        var allowUntrustedRootArg = allowUntrustedRoot ? "-AllowUntrustedRoot" : string.Empty;
                        var multiplePackagesPath  = $"{dir}{Path.DirectorySeparatorChar}*.nupkg";

                        // Act
                        var commandResult = CommandRunner.Run(
                            _nugetExePath,
                            dir,
                            $"trusted-signers add {multiplePackagesPath} -Name signer -Author {allowUntrustedRootArg} -Config {nugetConfigPath}",
                            waitForExit: true);

                        // Assert
                        commandResult.Success.Should().BeFalse();
                        commandResult.AllOutput.Should().Contain(string.Format(CultureInfo.CurrentCulture,
                                                                               "Multiple nupkg files detected on '{0}' path to trust, only 1 is allowed.",
                                                                               multiplePackagesPath));
                    }
        }
        public void GetAllowListEntries_WithoutTrustedSignersSection_ReturnsEmptyList()
        {
            // Arrange
            var config = @"
<configuration>
</configuration>";

            var nugetConfigPath = "NuGet.Config";

            using (var mockBaseDirectory = TestDirectory.Create())
            {
                SettingsTestUtils.CreateConfigurationFile(nugetConfigPath, mockBaseDirectory, config);

                // Act and Assert
                var settings = new Settings(mockBaseDirectory);
                settings.Should().NotBeNull();

                var entries = TrustedSignersProvider.GetAllowListEntries(settings, NullLogger.Instance);
                entries.Should().NotBeNull();
                entries.Should().BeEmpty();
            }
        }
Пример #27
0
        public async Task DotnetTrust_RepositoryAction_TryAddSameRepository_Fails()
        {
            // Arrange
            var nugetConfigFileName = "NuGet.Config";
            var package             = new SimpleTestPackageContext();

            using (SimpleTestPathContext pathContext = _msbuildFixture.CreateSimpleTestPathContext())
                using (MemoryStream zipStream = await package.CreateAsStreamAsync())
                    using (TrustedTestCert <TestCertificate> trustedTestCert = SigningTestUtility.GenerateTrustedTestCertificate())
                    {
                        var certFingerprint   = SignatureTestUtility.GetFingerprint(trustedTestCert.Source.Cert, HashAlgorithmName.SHA256);
                        var repoServiceIndex  = "https://serviceindex.test/v3/index.json";
                        var signedPackagePath = await SignedArchiveTestUtility.RepositorySignPackageAsync(trustedTestCert.Source.Cert, package, pathContext.PackageSource, new Uri(repoServiceIndex));

                        var config = $@"<?xml version=""1.0"" encoding=""utf-8""?>
                <configuration>
                </configuration>";
                        SettingsTestUtils.CreateConfigurationFile(nugetConfigFileName, pathContext.WorkingDirectory, config);
                        var nugetConfigPath = Path.Combine(pathContext.WorkingDirectory, nugetConfigFileName);

                        // Act
                        CommandRunnerResult resultAdd = _msbuildFixture.RunDotnet(
                            pathContext.SolutionRoot,
                            $"nuget trust repository nuget {signedPackagePath} --configfile {nugetConfigPath}");

                        // Assert
                        resultAdd.Success.Should().BeTrue();

                        // Try to add same repository again
                        resultAdd = _msbuildFixture.RunDotnet(
                            pathContext.SolutionRoot,
                            $"nuget trust repository nuget {signedPackagePath} --configfile {nugetConfigPath}", ignoreExitCode: true);

                        // Main assert
                        resultAdd.Success.Should().BeFalse();
                        resultAdd.AllOutput.Should().Contain("error: A trusted signer 'nuget' already exists.");
                        resultAdd.AllOutput.Should().NotContain("--help");
                    }
        }
        public void GetAllowListEntries_TrustedAuthor_WithOneCertificate_ParsedCorrectly()
        {
            // Arrange
            var config = @"
<configuration>
    <trustedSigners>
        <author name=""author1"">
            <certificate fingerprint=""abc"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
        </author>
        <author name=""author2"">
            <certificate fingerprint=""def"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" />
        </author>
    </trustedSigners>
</configuration>";

            var nugetConfigPath = "NuGet.Config";

            using (var mockBaseDirectory = TestDirectory.Create())
            {
                SettingsTestUtils.CreateConfigurationFile(nugetConfigPath, mockBaseDirectory, config);

                // Act and Assert
                var settings = new Settings(mockBaseDirectory);
                settings.Should().NotBeNull();

                var entries = TrustedSignersProvider.GetAllowListEntries(settings, NullLogger.Instance);
                entries.Should().NotBeNull();
                entries.Count.Should().Be(2);

                var expectedEntries = new List <VerificationAllowListEntry>()
                {
                    new TrustedSignerAllowListEntry(VerificationTarget.Author, SignaturePlacement.PrimarySignature, "abc", HashAlgorithmName.SHA256),
                    new TrustedSignerAllowListEntry(VerificationTarget.Author, SignaturePlacement.PrimarySignature, "def", HashAlgorithmName.SHA256)
                };

                entries.Should().BeEquivalentTo(expectedEntries);
            }
        }
        public void GetClientPolicy_WhenNoClientPolicy_DefaultsToAccept()
        {
            // Arrange
            var config = @"
<configuration>
</configuration>";

            var nugetConfigPath = "NuGet.Config";

            using (var mockBaseDirectory = TestDirectory.Create())
            {
                SettingsTestUtils.CreateConfigurationFile(nugetConfigPath, mockBaseDirectory, config);

                // Act and Assert
                var settings = new Settings(mockBaseDirectory);
                settings.Should().NotBeNull();

                var verifierSettings = SignedPackageVerifierSettings.GetClientPolicy(settings, NullLogger.Instance);

                verifierSettings.AllowUnsigned.Should().Be(true);
                verifierSettings.AllowIllegal.Should().Be(true);
                verifierSettings.AllowUntrusted.Should().Be(true);
                verifierSettings.AllowIgnoreTimestamp.Should().Be(true);
                verifierSettings.AllowMultipleTimestamps.Should().Be(true);
                verifierSettings.AllowNoTimestamp.Should().Be(true);
                verifierSettings.AllowUnknownRevocation.Should().Be(true);
                verifierSettings.ReportUnknownRevocation.Should().Be(false);
                verifierSettings.AllowNoRepositoryCertificateList.Should().Be(true);
                verifierSettings.AllowNoClientCertificateList.Should().Be(true);
                verifierSettings.VerificationTarget.Should().Be(VerificationTarget.All);
                verifierSettings.SignaturePlacement.Should().Be(SignaturePlacement.Any);
                verifierSettings.RepositoryCountersignatureVerificationBehavior.Should().Be(SignatureVerificationBehavior.IfExistsAndIsNecessary);
                verifierSettings.RevocationMode.Should().Be(RevocationMode.Online);
                verifierSettings.RepositoryCertificateList.Should().BeNull();
                verifierSettings.ClientCertificateList.Should().BeEmpty();
            }
        }
Пример #30
0
        public void EvaluateSources_GivenConfigWithCredentials_ReturnsPackageSourceWithCredentials()
        {
            using (var mockBaseDirectory = TestDirectory.Create())
            {
                List <PackageSource> source = new List <PackageSource>()
                {
                    new PackageSource("https://contoso.org/v3/index.json"), new PackageSource("b")
                };

                var nugetConfigFileName = "NuGet.Config";
                var config = @"<?xml version=""1.0"" encoding=""utf-8""?>
                            <configuration>
                                <packageSources>
                                    <add key=""Contoso"" value=""https://contoso.org/v3/index.json"" />
                                    <add key=""b"" value =""b"" />
                                </packageSources>
                                <packageSourceCredentials>
                                    <Contoso>
                                        <add key=""Username"" value=""user @contoso.com"" />
                                        <add key=""Password"" value=""..."" />
                                    </Contoso>
                                </packageSourceCredentials>
                            </configuration>";

                var configPath = Path.Combine(mockBaseDirectory, nugetConfigFileName);
                SettingsTestUtils.CreateConfigurationFile(nugetConfigFileName, mockBaseDirectory, config);
                var settingsLoadContext = new SettingsLoadingContext();

                var settings = Settings.LoadImmutableSettingsGivenConfigPaths(new string[] { configPath }, settingsLoadContext);
                var result   = AddPackageCommandUtility.EvaluateSources(source, settings.GetConfigFilePaths());

                // Asert
                Assert.Equal(2, result.Count);
                Assert.NotEqual(null, result[0].Credentials);
            }
        }