public async Task GetTrustResultAsync_WithInvalidSignature_Throws() { var package = new SimpleTestPackageContext(); var timestampService = await _testFixture.GetDefaultTrustedTimestampServiceAsync(); using (var directory = TestDirectory.Create()) using (var testCertificate = new X509Certificate2(_trustedTestCert.Source.Cert)) { var packageFilePath = await SignedArchiveTestUtility.AuthorSignPackageAsync( testCertificate, package, directory, timestampService.Url); using (var packageReader = new PackageArchiveReader(packageFilePath)) { var signature = await packageReader.GetPrimarySignatureAsync(CancellationToken.None); var invalidSignature = SignatureTestUtility.GenerateInvalidPrimarySignature(signature); var provider = new SignatureTrustAndValidityVerificationProvider(); var result = await provider.GetTrustResultAsync( packageReader, invalidSignature, _defaultSettings, CancellationToken.None); var issue = result.Issues.FirstOrDefault(log => log.Code == NuGetLogCode.NU3012); Assert.NotNull(issue); Assert.Contains("validation failed.", issue.Message); } } }
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 async Task GetTrustResultAsync_VerifyWithCertificateInAllowList_Success() { // Arrange var nupkg = new SimpleTestPackageContext(); using (var dir = TestDirectory.Create()) using (var testCertificate = new X509Certificate2(_trustedTestCert.Source.Cert)) { var certificateFingerprintString = SignatureTestUtility.GetFingerprint(testCertificate, HashAlgorithmName.SHA256); var signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync(testCertificate, nupkg, dir); var allowListHashes = new[] { certificateFingerprintString, "abc" }; var allowList = allowListHashes.Select(hash => new CertificateHashAllowListEntry(VerificationTarget.Primary, hash)).ToList(); var trustProviders = new[] { new AllowListVerificationProvider(allowList) }; var verifier = new PackageSignatureVerifier(trustProviders, _settings); using (var packageReader = new PackageArchiveReader(signedPackagePath)) { // Act var result = await verifier.VerifySignaturesAsync(packageReader, CancellationToken.None); // Assert result.Valid.Should().BeTrue(); } } }
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); } }
public async Task VerifySignaturesAsync_ExpiredCertificateAndTimestampWithTooLargeRange_FailsAsync() { ISigningTestServer testServer = await _testFixture.GetSigningTestServerAsync(); CertificateAuthority ca = await _testFixture.GetDefaultTrustedCertificateAuthorityAsync(); var accuracy = new BcAccuracy(seconds: new DerInteger(30), millis: null, micros: null); var serviceOptions = new TimestampServiceOptions() { Accuracy = accuracy }; TimestampService timestampService = TimestampService.Create(ca, serviceOptions); AsymmetricCipherKeyPair keyPair = SigningTestUtility.GenerateKeyPair(publicKeyLength: 2048); DateTimeOffset now = DateTimeOffset.UtcNow; var issueOptions = new IssueCertificateOptions() { KeyPair = keyPair, NotAfter = now.AddSeconds(10), NotBefore = now.AddSeconds(-2), SubjectName = new X509Name("CN=NuGet Test Expired Certificate") }; BcX509Certificate bcCertificate = ca.IssueCertificate(issueOptions); using (testServer.RegisterResponder(timestampService)) using (TestDirectory directory = TestDirectory.Create()) using (X509Certificate2 certificate = CertificateUtilities.GetCertificateWithPrivateKey(bcCertificate, keyPair)) { var packageContext = new SimpleTestPackageContext(); string signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync( certificate, packageContext, directory, timestampService.Url); await SignatureTestUtility.WaitForCertificateExpirationAsync(certificate); var verifier = new PackageSignatureVerifier(_trustProviders); using (var packageReader = new PackageArchiveReader(signedPackagePath)) { VerifySignaturesResult results = await verifier.VerifySignaturesAsync(packageReader, _verifyCommandSettings, CancellationToken.None); PackageVerificationResult result = results.Results.Single(); Assert.False(results.IsValid); Assert.Equal(SignatureVerificationStatus.Disallowed, result.Trust); Assert.Equal(1, result.Issues.Count(issue => issue.Level == LogLevel.Error)); Assert.Equal(0, result.Issues.Count(issue => issue.Level == LogLevel.Warning)); Assert.Contains(result.Issues, issue => issue.Code == NuGetLogCode.NU3037 && issue.Level == LogLevel.Error && issue.Message.Contains("validity period has expired.")); } } }
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 async Task VerifySignaturesAsync_WithExpiredPrimarySignature_ValidCountersignature_AndPrimarySignatureExpiredAtCountersignTime_FailsAsync() { // Arrange var nupkg = new SimpleTestPackageContext(); TimestampService timestampService = await _testFixture.GetDefaultTrustedTimestampServiceAsync(); var settings = new SignedPackageVerifierSettings( allowUnsigned: false, allowIllegal: false, allowUntrusted: false, allowIgnoreTimestamp: true, allowMultipleTimestamps: true, allowNoTimestamp: true, allowUnknownRevocation: true, reportUnknownRevocation: true, verificationTarget: VerificationTarget.All, signaturePlacement: SignaturePlacement.Any, repositoryCountersignatureVerificationBehavior: SignatureVerificationBehavior.IfExists, revocationMode: RevocationMode.Online); using (TestDirectory dir = TestDirectory.Create()) using (TrustedTestCert <TestCertificate> trustedCertificate = _testFixture.CreateTrustedTestCertificateThatWillExpireSoon()) using (var willExpireCert = new X509Certificate2(trustedCertificate.Source.Cert)) using (var repoTestCertificate = new X509Certificate2(_trustedTestCert.Source.Cert)) { string signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync( willExpireCert, nupkg, dir); await SignatureTestUtility.WaitForCertificateExpirationAsync(willExpireCert); string countersignedPackagePath = await SignedArchiveTestUtility.RepositorySignPackageAsync( repoTestCertificate, signedPackagePath, dir, TestServiceIndexUrl, timestampService.Url); var verifier = new PackageSignatureVerifier(_trustProviders); using (var packageReader = new PackageArchiveReader(countersignedPackagePath)) { // Act VerifySignaturesResult result = await verifier.VerifySignaturesAsync(packageReader, settings, CancellationToken.None); IEnumerable <PackageVerificationResult> resultsWithErrors = result.Results.Where(r => r.GetErrorIssues().Any()); // Assert result.IsValid.Should().BeFalse(); resultsWithErrors.Count().Should().Be(1); } } }
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); } }
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 async Task Verify_RepositorySignedPackage_WithAuthorItemUntrustedCertificate_Fails(string allowUntrustedRoot, bool verifyCertificateFingerprint) { IX509StoreCertificate storeCertificate = _signFixture.UntrustedSelfIssuedCertificateInCertificateStore; // Arrange using (var pathContext = new SimpleTestPathContext()) { var nupkg = new SimpleTestPackageContext("A", "1.0.0"); string testDirectory = pathContext.WorkingDirectory; await SimpleTestPackageUtility.CreatePackagesAsync(testDirectory, nupkg); string packagePath = Path.Combine(testDirectory, nupkg.PackageName); //Act string certificateFingerprintString = SignatureTestUtility.GetFingerprint(storeCertificate.Certificate, HashAlgorithmName.SHA256); string repoServiceIndex = "https://serviceindex.test/v3/index.json"; string signedPackagePath = await SignedArchiveTestUtility.RepositorySignPackageAsync(storeCertificate.Certificate, packagePath, pathContext.PackageSource, new Uri(repoServiceIndex)); // Arrange string trustedSignersSectionContent = $@" <trustedSigners> <author name=""MyCert""> <certificate fingerprint=""{certificateFingerprintString}"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""{allowUntrustedRoot}"" /> </author> </trustedSigners> "; SimpleTestSettingsContext.AddSectionIntoNuGetConfig(pathContext.WorkingDirectory, trustedSignersSectionContent, "configuration"); string fingerprint = verifyCertificateFingerprint ? $"--certificate-fingerprint {certificateFingerprintString} --certificate-fingerprint def" : string.Empty; //Act CommandRunnerResult verifyResult = _msbuildFixture.RunDotnet( testDirectory, $"nuget verify {signedPackagePath} {fingerprint}", ignoreExitCode: true); // Assert verifyResult.Success.Should().BeFalse(because: verifyResult.AllOutput); verifyResult.AllOutput.Should().Contain(_noTimestamperWarningCode); verifyResult.AllOutput.Should().Contain(_noMatchingCertErrorCode); verifyResult.AllOutput.Should().Contain("This package is signed but not by a trusted signer."); if (bool.TryParse(allowUntrustedRoot, out bool parsed) && !parsed) { verifyResult.AllOutput.Should().Contain(_primarySignatureInvalidErrorCode); } else { verifyResult.AllOutput.Should().NotContain(_primarySignatureInvalidErrorCode); } } }
public async Task Verify_RepositorySignedPackage_WithRepositoryItemTrustedCertificate_AllowUntrustedRootSet_CorrectOwners_Succeeds(string allowUntrustedRoot, bool verifyCertificateFingerprint) { // Arrange IX509StoreCertificate storeCertificate = _signFixture.DefaultCertificate; using (var pathContext = new SimpleTestPathContext()) { var package = new SimpleTestPackageContext(); string certFingerprint = SignatureTestUtility.GetFingerprint(storeCertificate.Certificate, HashAlgorithmName.SHA256); var packageOwners = new List <string>() { "nuget", "contoso" }; string repoServiceIndex = "https://serviceindex.test/v3/index.json"; string signedPackagePath = await SignedArchiveTestUtility.RepositorySignPackageAsync( storeCertificate.Certificate, package, pathContext.PackageSource, new Uri(repoServiceIndex), timestampService : null, packageOwners); string testDirectory = pathContext.WorkingDirectory; string trustedSignersSectionContent = $@" <trustedSigners> <repository name=""NuGetTrust"" serviceIndex=""{repoServiceIndex}""> <certificate fingerprint=""{certFingerprint}"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""{allowUntrustedRoot}"" /> <owners>nuget;Contoso</owners> </repository> </trustedSigners> "; SimpleTestSettingsContext.AddSectionIntoNuGetConfig(testDirectory, trustedSignersSectionContent, "configuration"); string fingerprint = verifyCertificateFingerprint ? $"--certificate-fingerprint {certFingerprint} --certificate-fingerprint DEF" : string.Empty; //Act CommandRunnerResult verifyResult = _msbuildFixture.RunDotnet( testDirectory, $"nuget verify {signedPackagePath} {fingerprint}", ignoreExitCode: true); // Assert // For certificate with trusted root setting allowUntrustedRoot value true/false doesn't matter. // Owners is casesensitive, here owner "nuget" matches verifyResult.Success.Should().BeTrue(); verifyResult.AllOutput.Should().Contain(_noTimestamperWarningCode); } }
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 Verify_RepositorySignedPackage_WithRepositoryItemUntrustedCertificate_AllowUntrustedRootSetTrue_WrongOwners_Fails(string allowUntrustedRoot, bool verifyCertificateFingerprint) { IX509StoreCertificate storeCertificate = _signFixture.UntrustedSelfIssuedCertificateInCertificateStore; // Arrange using (var pathContext = new SimpleTestPathContext()) { var nupkg = new SimpleTestPackageContext("A", "1.0.0"); await SimpleTestPackageUtility.CreatePackagesAsync(pathContext.WorkingDirectory, nupkg); string packagePath = Path.Combine(pathContext.WorkingDirectory, nupkg.PackageName); //Act var certificateFingerprintString = SignatureTestUtility.GetFingerprint(storeCertificate.Certificate, HashAlgorithmName.SHA256); var packageOwners = new List <string>() { "nuget", "contoso" }; string repoServiceIndex = "https://serviceindex.test/v3/index.json"; string signedPackagePath = await SignedArchiveTestUtility.RepositorySignPackageAsync(storeCertificate.Certificate, packagePath, pathContext.PackageSource, new Uri(repoServiceIndex), null, packageOwners); // Arrange string trustedSignersSectionContent = $@" <trustedSigners> <repository name=""MyCert"" serviceIndex = ""{repoServiceIndex}""> <certificate fingerprint=""{certificateFingerprintString}"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""{allowUntrustedRoot}"" /> <owners>Nuget;Contoso</owners> </repository> </trustedSigners> "; SimpleTestSettingsContext.AddSectionIntoNuGetConfig(pathContext.WorkingDirectory, trustedSignersSectionContent, "configuration"); string fingerprint = verifyCertificateFingerprint ? $"--certificate-fingerprint {certificateFingerprintString} --certificate-fingerprint DEF" : string.Empty; //Act CommandRunnerResult verifyResult = _msbuildFixture.RunDotnet( pathContext.WorkingDirectory, $"nuget verify {signedPackagePath} {fingerprint}", ignoreExitCode: true); // Assert // Owners is casesensitive, owner info should be "nuget;contoso" not "Nuget;Contoso" verifyResult.Success.Should().BeFalse(because: verifyResult.AllOutput); verifyResult.AllOutput.Should().Contain(_noMatchingCertErrorCode); verifyResult.AllOutput.Should().Contain("This package is signed but not by a trusted signer."); } }
public async Task GetSigningCertificateFingerprint_SuccessfullyHashesMultipleAlgorithms() { using (var test = await VerifyTest.CreateAsync(settings: null, certificate: _untrustedTestCertificate.Cert)) { var sha256 = test.PrimarySignature.GetSigningCertificateFingerprint(HashAlgorithmName.SHA256); var sha384 = test.PrimarySignature.GetSigningCertificateFingerprint(HashAlgorithmName.SHA384); var sha512 = test.PrimarySignature.GetSigningCertificateFingerprint(HashAlgorithmName.SHA512); var expectedSha256 = SignatureTestUtility.GetFingerprint(_untrustedTestCertificate.Cert, HashAlgorithmName.SHA256); var expectedSha384 = SignatureTestUtility.GetFingerprint(_untrustedTestCertificate.Cert, HashAlgorithmName.SHA384); var expectedSha512 = SignatureTestUtility.GetFingerprint(_untrustedTestCertificate.Cert, HashAlgorithmName.SHA512); Assert.Equal(sha256, expectedSha256, StringComparer.Ordinal); Assert.Equal(sha384, expectedSha384, StringComparer.Ordinal); Assert.Equal(sha512, expectedSha512, StringComparer.Ordinal); } }
public async Task Verify_RepositorySignedPackage_WithRepositoryItemUntrustedCertificate_AllowUntrustedRootSetTrue_CorrectOwners_Succeeds(string allowUntrustedRoot, bool verifyCertificateFingerprint) { // Arrange using (var pathContext = new SimpleTestPathContext()) using (var testCertificate = new X509Certificate2(_testFixture.UntrustedSelfIssuedCertificateInCertificateStore)) { var nupkg = new SimpleTestPackageContext("A", "1.0.0"); await SimpleTestPackageUtility.CreatePackagesAsync(pathContext.WorkingDirectory, nupkg); string packagePath = Path.Combine(pathContext.WorkingDirectory, nupkg.PackageName); //Act string certificateFingerprintString = SignatureTestUtility.GetFingerprint(testCertificate, HashAlgorithmName.SHA256); var packageOwners = new List <string>() { "nuget", "contoso" }; string repoServiceIndex = "https://serviceindex.test/v3/index.json"; string signedPackagePath = await SignedArchiveTestUtility.RepositorySignPackageAsync(testCertificate, packagePath, pathContext.PackageSource, new Uri(repoServiceIndex), null, packageOwners); // Arrange string trustedSignersSectionContent = $@" <trustedSigners> <repository name=""MyCert"" serviceIndex = ""{repoServiceIndex}""> <certificate fingerprint=""{certificateFingerprintString}"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""{allowUntrustedRoot}"" /> <owners>nuget;Contoso</owners> </repository> </trustedSigners> "; SimpleTestSettingsContext.AddSectionIntoNuGetConfig(pathContext.WorkingDirectory, trustedSignersSectionContent, "configuration"); string fingerprint = verifyCertificateFingerprint ? $"-CertificateFingerprint {certificateFingerprintString};def" : string.Empty; // Act CommandRunnerResult verifyResult = CommandRunner.Run( _nugetExePath, pathContext.PackageSource, $"verify {signedPackagePath} -Signatures {fingerprint}", waitForExit: true); // Assert // Owners is casesensitive, here owner "nuget" matches verifyResult.Success.Should().BeTrue(); verifyResult.AllOutput.Should().Contain(_noTimestamperWarningCode); } }
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); } }
private static void TamperSignature(string packageFilePath) { var packageSignature = ReadPackageSignature(packageFilePath); var randomBytes = new byte[packageSignature.Length]; using (var rng = RandomNumberGenerator.Create()) { rng.GetBytes(randomBytes); } var fileBytes = File.ReadAllBytes(packageFilePath); var newFileBytes = SignatureTestUtility.FindAndReplaceSequence( fileBytes, packageSignature, randomBytes); File.WriteAllBytes(packageFilePath, newFileBytes); }
public async Task VerifySignaturesAsync_ExpiredCertificateAndTimestamp_SuccessAsync() { CertificateAuthority ca = await _testFixture.GetDefaultTrustedCertificateAuthorityAsync(); TimestampService timestampService = await _testFixture.GetDefaultTrustedTimestampServiceAsync(); AsymmetricCipherKeyPair keyPair = SigningTestUtility.GenerateKeyPair(publicKeyLength: 2048); DateTimeOffset now = DateTimeOffset.UtcNow; var issueOptions = new IssueCertificateOptions() { KeyPair = keyPair, NotAfter = now.AddSeconds(10), NotBefore = now.AddSeconds(-2), SubjectName = new X509Name("CN=NuGet Test Expired Certificate") }; BcX509Certificate bcCertificate = ca.IssueCertificate(issueOptions); using (TestDirectory directory = TestDirectory.Create()) using (X509Certificate2 certificate = CertificateUtilities.GetCertificateWithPrivateKey(bcCertificate, keyPair)) { var packageContext = new SimpleTestPackageContext(); string signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync( certificate, packageContext, directory, timestampService.Url); await SignatureTestUtility.WaitForCertificateExpirationAsync(certificate); var verifier = new PackageSignatureVerifier(_trustProviders); using (var packageReader = new PackageArchiveReader(signedPackagePath)) { VerifySignaturesResult result = await verifier.VerifySignaturesAsync(packageReader, _verifyCommandSettings, CancellationToken.None); PackageVerificationResult trustProvider = result.Results.Single(); Assert.True(result.IsValid); Assert.Equal(SignatureVerificationStatus.Valid, trustProvider.Trust); Assert.Equal(0, trustProvider.Issues.Count(issue => issue.Level == LogLevel.Error)); Assert.Equal(0, trustProvider.Issues.Count(issue => issue.Level == LogLevel.Warning)); } } }
public async Task Verify_RepositorySignedPackage_WithRepositoryItemTrustedCertificate_AllowUntrustedRootSet_WrongOwners_Fails(string allowUntrustedRoot, bool verifyCertificateFingerprint) { // Arrange TrustedTestCert <TestCertificate> cert = _testFixture.TrustedTestCertificateChain.Leaf; using (var pathContext = new SimpleTestPathContext()) { var package = new SimpleTestPackageContext(); string certFingerprint = SignatureTestUtility.GetFingerprint(cert.Source.Cert, HashAlgorithmName.SHA256); var packageOwners = new List <string>() { "nuget", "contoso" }; string repoServiceIndex = "https://serviceindex.test/v3/index.json"; string signedPackagePath = await SignedArchiveTestUtility.RepositorySignPackageAsync(cert.Source.Cert, package, pathContext.PackageSource, new Uri(repoServiceIndex), null, packageOwners); string testDirectory = pathContext.WorkingDirectory; // Arrange string trustedSignersSectionContent = $@" <trustedSigners> <repository name=""NuGetTrust"" serviceIndex=""{repoServiceIndex}""> <certificate fingerprint=""{certFingerprint}"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""{allowUntrustedRoot}"" /> <owners>Nuget;Contoso</owners> </repository> </trustedSigners> "; SimpleTestSettingsContext.AddSectionIntoNuGetConfig(testDirectory, trustedSignersSectionContent, "configuration"); string fingerprint = verifyCertificateFingerprint ? $"-CertificateFingerprint {certFingerprint};def" : string.Empty; //Act CommandRunnerResult verifyResult = CommandRunner.Run( _nugetExePath, pathContext.PackageSource, $"verify {signedPackagePath} -Signatures {fingerprint}", waitForExit: true); // Assert // Owners is casesensitive, owner info should be "nuget;contoso" not "Nuget;Contoso" verifyResult.Success.Should().BeFalse(); verifyResult.AllOutput.Should().Contain(_noMatchingCertErrorCode); } }
public async Task VerifyCommand_AuthorSignedPackage_WithUntrustedCertificate_AllowUntrustedRootIsSetTrue_WrongNugetConfig_Fails() { IX509StoreCertificate storeCertificate = _signFixture.UntrustedSelfIssuedCertificateInCertificateStore; // Arrange using (var pathContext = new SimpleTestPathContext()) { var nupkg = new SimpleTestPackageContext("A", "1.0.0"); //Act string signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync(storeCertificate.Certificate, nupkg, pathContext.WorkingDirectory); string certificateFingerprintString = SignatureTestUtility.GetFingerprint(storeCertificate.Certificate, HashAlgorithmName.SHA256); // Arrange string nugetConfigPath = Path.Combine(pathContext.WorkingDirectory, NuGet.Configuration.Settings.DefaultSettingsFileName); string nugetConfigPath2 = Path.Combine(pathContext.WorkingDirectory, "nuget2.config"); // nuget2.config doesn't have change for trustedSigners File.Copy(nugetConfigPath, nugetConfigPath2); string trustedSignersSectionContent = $@" <trustedSigners> <author name=""MyCert""> <certificate fingerprint=""{certificateFingerprintString}"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""true"" /> </author> </trustedSigners> "; SimpleTestSettingsContext.AddSectionIntoNuGetConfig(pathContext.WorkingDirectory, trustedSignersSectionContent, "configuration"); //Act // pass custom nuget2.config file, but doesn't have trustedSigners section CommandRunnerResult verifyResult = _msbuildFixture.RunDotnet( pathContext.WorkingDirectory, $"nuget verify {signedPackagePath} --all --certificate-fingerprint {certificateFingerprintString} --certificate-fingerprint def --configfile {nugetConfigPath2}", ignoreExitCode: true); // Assert // allowUntrustedRoot is not set true in nuget2.config, but in nuget.config, so verify fails. verifyResult.Success.Should().BeFalse(); verifyResult.AllOutput.Should().Contain(_noTimestamperWarningCode); verifyResult.AllOutput.Should().Contain(_primarySignatureInvalidErrorCode); } }
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"); } }
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); } }
public async Task Verify_RepositorySignedPackage_WithRepositoryItemUntrustedCertificate_AllowUntrustedRootSetFalse_Fails(string allowUntrustedRoot, bool verifyCertificateFingerprint) { // Arrange using (var pathContext = new SimpleTestPathContext()) using (var testCertificate = new X509Certificate2(_testFixture.UntrustedSelfIssuedCertificateInCertificateStore)) { var nupkg = new SimpleTestPackageContext("A", "1.0.0"); string testDirectory = pathContext.WorkingDirectory; await SimpleTestPackageUtility.CreatePackagesAsync(testDirectory, nupkg); string packagePath = Path.Combine(testDirectory, nupkg.PackageName); //Act string certificateFingerprintString = SignatureTestUtility.GetFingerprint(testCertificate, HashAlgorithmName.SHA256); string repoServiceIndex = "https://serviceindex.test/v3/index.json"; string signedPackagePath = await SignedArchiveTestUtility.RepositorySignPackageAsync(testCertificate, packagePath, pathContext.PackageSource, new Uri(repoServiceIndex)); // Arrange string trustedSignersSectionContent = $@" <trustedSigners> <repository name=""MyCert"" serviceIndex = ""{repoServiceIndex}""> <certificate fingerprint=""{certificateFingerprintString}"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""{allowUntrustedRoot}"" /> </repository> </trustedSigners> "; SimpleTestSettingsContext.AddSectionIntoNuGetConfig(pathContext.WorkingDirectory, trustedSignersSectionContent, "configuration"); string fingerprint = verifyCertificateFingerprint ? $"-CertificateFingerprint {certificateFingerprintString};def" : string.Empty; // Act CommandRunnerResult verifyResult = CommandRunner.Run( _nugetExePath, pathContext.PackageSource, $"verify {signedPackagePath} -Signatures {fingerprint}", waitForExit: true); // Assert // Unless allowUntrustedRoot is set true in nuget.config verify always fails for cert without trusted root. verifyResult.Success.Should().BeFalse(because: verifyResult.AllOutput); verifyResult.AllOutput.Should().Contain(_noTimestamperWarningCode); verifyResult.AllOutput.Should().Contain(_primarySignatureInvalidErrorCode); verifyResult.AllOutput.Should().Contain("The repository primary signature's signing certificate is not trusted by the trust provider."); } }
public async Task VerifyCommand_AuthorSignedPackage_WithUntrustedCertificate_AllowUntrustedRootIsSetTrue_CorrectNugetConfig_Succeed() { // Arrange using (var pathContext = new SimpleTestPathContext()) using (var testCertificate = new X509Certificate2(_testFixture.UntrustedSelfIssuedCertificateInCertificateStore)) { var nupkg = new SimpleTestPackageContext("A", "1.0.0"); //Act string signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync(testCertificate, nupkg, pathContext.WorkingDirectory); string certificateFingerprintString = SignatureTestUtility.GetFingerprint(testCertificate, HashAlgorithmName.SHA256); // Arrange string nugetConfigPath = Path.Combine(pathContext.WorkingDirectory, NuGet.Configuration.Settings.DefaultSettingsFileName); string nugetConfigPath2 = Path.Combine(pathContext.WorkingDirectory, "nuget2.config"); File.Copy(nugetConfigPath, nugetConfigPath2); string trustedSignersSectionContent = $@" <trustedSigners> <author name=""MyCert""> <certificate fingerprint=""{certificateFingerprintString}"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""true"" /> </author> </trustedSigners> "; SimpleTestSettingsContext.AddSectionIntoNuGetConfig(nugetConfigPath2, trustedSignersSectionContent, "configuration"); // Act // pass custom nuget2.config file, it has trustedSigners section CommandRunnerResult verifyResult = CommandRunner.Run( _nugetExePath, pathContext.PackageSource, $"verify {signedPackagePath} -All -CertificateFingerprint {certificateFingerprintString};def -ConfigFile {nugetConfigPath2}", waitForExit: true); // Assert // allowUntrustedRoot is set true in nuget2.config, so verify succeeds. verifyResult.Success.Should().BeTrue(); verifyResult.AllOutput.Should().Contain(_noTimestamperWarningCode); } }
public async Task Verify_RepositorySignedPackage_WithRepositoryItemUntrustedCertificate_AllowUntrustedRootSetTrue_Succeeds(string allowUntrustedRoot, bool verifyCertificateFingerprint) { IX509StoreCertificate storeCertificate = _signFixture.UntrustedSelfIssuedCertificateInCertificateStore; // Arrange using (var pathContext = new SimpleTestPathContext()) { var nupkg = new SimpleTestPackageContext("A", "1.0.0"); string testDirectory = pathContext.WorkingDirectory; await SimpleTestPackageUtility.CreatePackagesAsync(testDirectory, nupkg); string packagePath = Path.Combine(testDirectory, nupkg.PackageName); //Act string certificateFingerprintString = SignatureTestUtility.GetFingerprint(storeCertificate.Certificate, HashAlgorithmName.SHA256); string repoServiceIndex = "https://serviceindex.test/v3/index.json"; string signedPackagePath = await SignedArchiveTestUtility.RepositorySignPackageAsync(storeCertificate.Certificate, packagePath, pathContext.PackageSource, new Uri(repoServiceIndex)); // Arrange string trustedSignersSectionContent = $@" <trustedSigners> <repository name=""MyCert"" serviceIndex = ""{repoServiceIndex}""> <certificate fingerprint=""{certificateFingerprintString}"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""{allowUntrustedRoot}"" /> </repository> </trustedSigners> "; SimpleTestSettingsContext.AddSectionIntoNuGetConfig(pathContext.WorkingDirectory, trustedSignersSectionContent, "configuration"); string fingerprint = verifyCertificateFingerprint ? $"--certificate-fingerprint {certificateFingerprintString} --certificate-fingerprint def" : string.Empty; //Act CommandRunnerResult verifyResult = _msbuildFixture.RunDotnet( testDirectory, $"nuget verify {signedPackagePath} {fingerprint}", ignoreExitCode: true); // Assert // If allowUntrustedRoot is set true in nuget.config then verify succeeds for cert with untrusted root. verifyResult.Success.Should().BeTrue(); verifyResult.AllOutput.Should().Contain(_noTimestamperWarningCode); } }
public async Task Verify_AuthorSignedPackage_WithRepositoryItemTrustedCertificate_Fails(string allowUntrustedRoot, bool verifyCertificateFingerprint) { // Arrange TrustedTestCert <TestCertificate> cert = _testFixture.TrustedTestCertificateChain.Leaf; using (var pathContext = new SimpleTestPathContext()) { var nupkg = new SimpleTestPackageContext("A", "1.0.0"); string testDirectory = pathContext.WorkingDirectory; await SimpleTestPackageUtility.CreatePackagesAsync(testDirectory, nupkg); //Act string certificateFingerprintString = SignatureTestUtility.GetFingerprint(cert.Source.Cert, HashAlgorithmName.SHA256); string signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync(cert.Source.Cert, nupkg, testDirectory); // Arrange string trustedSignersSectionContent = $@" <trustedSigners> <repository name=""MyCert"" serviceIndex=""{pathContext.PackageSource}""> <certificate fingerprint=""{certificateFingerprintString}"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""{allowUntrustedRoot}"" /> </repository> </trustedSigners> "; SimpleTestSettingsContext.AddSectionIntoNuGetConfig(pathContext.WorkingDirectory, trustedSignersSectionContent, "configuration"); string fingerprint = verifyCertificateFingerprint ? $"-CertificateFingerprint {certificateFingerprintString};def" : string.Empty; // Act CommandRunnerResult verifyResult = CommandRunner.Run( _nugetExePath, pathContext.PackageSource, $"verify {signedPackagePath} -Signatures {fingerprint}", waitForExit: true); // Assert verifyResult.Success.Should().BeFalse(because: verifyResult.AllOutput); verifyResult.AllOutput.Should().Contain(_noMatchingCertErrorCode); verifyResult.AllOutput.Should().Contain(_noTimestamperWarningCode); verifyResult.AllOutput.Should().Contain("This package is signed but not by a trusted signer."); } }
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"); } }
public async Task VerifyCommand_VerifyOnPackageSignedWithAllowedCertificateSucceedsAsync() { // Arrange var cert = _testFixture.TrustedTestCertificateChain.Leaf; var package = new SimpleTestPackageContext(); using (var dir = TestDirectory.Create()) using (var zipStream = await package.CreateAsStreamAsync()) { var packagePath = Path.Combine(dir, Guid.NewGuid().ToString()); zipStream.Seek(offset: 0, loc: SeekOrigin.Begin); using (var fileStream = File.OpenWrite(packagePath)) { zipStream.CopyTo(fileStream); } var signResult = CommandRunner.Run( _nugetExePath, dir, $"sign {packagePath} -CertificateFingerprint {cert.Source.Cert.Thumbprint} -CertificateStoreName {cert.StoreName} -CertificateStoreLocation {cert.StoreLocation}", waitForExit: true); signResult.Success.Should().BeTrue(); var certificateFingerprintString = SignatureTestUtility.GetFingerprint(cert.Source.Cert, HashAlgorithmName.SHA256); // Act var verifyResult = CommandRunner.Run( _nugetExePath, dir, $"verify {packagePath} -Signatures -CertificateFingerprint {certificateFingerprintString};abc;def", waitForExit: true); // Assert verifyResult.Success.Should().BeTrue(); verifyResult.AllOutput.Should().Contain(_noTimestamperWarningCode); } }
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 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"); } }