public async Task Verify_AuthorSignedRepositoryCounterSignedTimestampedPackage_SuccessAsync() { // Arrange var nupkg = new SimpleTestPackageContext(); X509Certificate2 defaultAuthorCertificate = await _testFixture.GetDefaultAuthorSigningCertificateAsync(); X509Certificate2 defaultRepositoryCertificate = await _testFixture.GetDefaultRepositorySigningCertificateAsync(); TimestampService timestampService = await _testFixture.GetDefaultTrustedTimestampServiceAsync(); using (TestDirectory dir = TestDirectory.Create()) using (var authorCertificate = new X509Certificate2(defaultAuthorCertificate)) using (var repositoryCertificate = new X509Certificate2(defaultRepositoryCertificate)) { string signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync( authorCertificate, nupkg, dir); string countersignedPackagePath = await SignedArchiveTestUtility.RepositorySignPackageAsync( repositoryCertificate, signedPackagePath, dir, ServiceIndexUrl, timestampService.Url); // Act CommandRunnerResult result = RunVerifyCommand(countersignedPackagePath); // Assert result.Success.Should().BeTrue(because: result.AllOutput); result.AllOutput.Should().Contain(_successfullyVerified); Regex.Matches(result.AllOutput, _noTimestamperWarning).Count.Should().Be(1); } }
private async Task <string> CreateSignedPackageAsync(TestDirectory dir, SigningTestType signature, X509Certificate2 authorcert, X509Certificate2 repocert) { var nupkg = new SimpleTestPackageContext(); var signedPackagePath = ""; if (signature == SigningTestType.Author || signature == SigningTestType.RepositoryCountersigned) { signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync(authorcert, nupkg, dir); } if (signature == SigningTestType.RepositoryPrimary) { signedPackagePath = await SignedArchiveTestUtility.RepositorySignPackageAsync(repocert, nupkg, dir, new Uri(@"https://api.v3serviceIndex.test/json"), packageOwners : new List <string>() { "owner1", "owner2", "owner3" }); } if (signature == SigningTestType.RepositoryCountersigned) { signedPackagePath = await SignedArchiveTestUtility.RepositorySignPackageAsync(repocert, signedPackagePath, dir, new Uri(@"https://api.v3serviceIndex.test/json"), packageOwners : new List <string>() { "owner1", "owner2", "owner3" }); } return(signedPackagePath); }
public async Task Install_RepoSignedPackage_SucceedsAsync() { // Arrange var nupkg = new SimpleTestPackageContext("A", "1.0.0"); using (var context = new SimpleTestPathContext()) using (var testCertificate = new X509Certificate2(_trustedTestCert.Source.Cert)) { await SignedArchiveTestUtility.RepositorySignPackageAsync(testCertificate, nupkg, context.WorkingDirectory, new Uri("https://v3serviceIndex.test/api/index.json")); var args = new string[] { nupkg.Id, "-Version", nupkg.Version, "-DirectDownload", "-NoCache", "-Source", context.WorkingDirectory, "-OutputDirectory", Path.Combine(context.WorkingDirectory, "packages") }; // Act var result = RunInstall(_nugetExePath, context, expectedExitCode: 0, additionalArgs: args); // Assert result.ExitCode.Should().Be(0); result.AllOutput.Should().Contain($"WARNING: {string.Format(_NU3027, SigningTestUtility.AddSignatureLogPrefix(_NU3027Message, nupkg.Identity, context.WorkingDirectory))}"); } }
public async Task GetTrustResultAsync_WithSignedAndCountersignedPackage_Succeeds() { // Arrange var nupkg = new SimpleTestPackageContext(); using (var dir = TestDirectory.Create()) using (var testCertificate = new X509Certificate2(_trustedTestCert.Source.Cert)) using (var trusted = SigningTestUtility.GenerateTrustedTestCertificate()) using (var counterCertificate = new X509Certificate2(trusted.Source.Cert)) { var signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync( testCertificate, nupkg, dir); var repositorySignedPackagePath = await SignedArchiveTestUtility.RepositorySignPackageAsync( counterCertificate, signedPackagePath, dir, new Uri("https://v3ServiceIndex.test/api/index")); var verifier = new PackageSignatureVerifier(_trustProviders); using (var packageReader = new PackageArchiveReader(repositorySignedPackagePath)) { // Act var result = await verifier.VerifySignaturesAsync(packageReader, SignedPackageVerifierSettings.GetVerifyCommandDefaultPolicy(), CancellationToken.None); var resultsWithErrors = result.Results.Where(r => r.GetErrorIssues().Any()); // Assert result.Valid.Should().BeTrue(); resultsWithErrors.Count().Should().Be(0); } } }
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_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 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 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 VerifySignaturesAsync_WithExpiredPrimarySignature_ValidCountersignature_AndPrimarySignatureExpiredAtCountersignTime_Fails() { // Arrange var nupkg = new SimpleTestPackageContext(); var timestampService = await _testFixture.GetDefaultTrustedTimestampServiceAsync(); var settings = new SignedPackageVerifierSettings( allowUnsigned: false, allowIllegal: false, allowUntrusted: false, allowIgnoreTimestamp: true, allowMultipleTimestamps: true, allowNoTimestamp: true, allowUnknownRevocation: true, alwaysVerifyCountersignature: true, allowNoClientCertificateList: true, allowNoRepositoryCertificateList: true); using (var dir = TestDirectory.Create()) using (var willExpireCert = new X509Certificate2(_testFixture.TrustedTestCertificateWillExpireIn5Seconds.Source.Cert)) using (var repoTestCertificate = new X509Certificate2(_trustedTestCert.Source.Cert)) { DateTimeOffset certExpiration = DateTime.SpecifyKind(willExpireCert.NotAfter, DateTimeKind.Local); var signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync( willExpireCert, nupkg, dir); // Wait for cert to expire while (certExpiration > DateTimeOffset.Now) { Thread.Sleep(100); } var countersignedPackagePath = await SignedArchiveTestUtility.RepositorySignPackageAsync(repoTestCertificate, signedPackagePath, dir, new Uri("https://v3serviceIndex.test/api/index.json"), timestampService.Url); var verifier = new PackageSignatureVerifier(_trustProviders); using (var packageReader = new PackageArchiveReader(countersignedPackagePath)) { // Act var result = await verifier.VerifySignaturesAsync(packageReader, settings, CancellationToken.None); var resultsWithErrors = result.Results.Where(r => r.GetErrorIssues().Any()); // Assert result.Valid.Should().BeFalse(); resultsWithErrors.Count().Should().Be(1); } } }
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); } }
internal static async Task <Test> CreateRepositoryPrimarySignedPackageAsync( X509Certificate2 certificate, Uri timestampServiceUrl = null) { var packageContext = new SimpleTestPackageContext(); var directory = TestDirectory.Create(); var signedPackagePath = await SignedArchiveTestUtility.RepositorySignPackageAsync( certificate, packageContext, directory, new Uri("https://nuget.test"), timestampServiceUrl); return(new Test(directory, new FileInfo(signedPackagePath))); }
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 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 WithExpiredAuthorCertificateAtCountersigning_InstallFromPMCForPR_WarnAsync(ProjectTemplate projectTemplate) { // Arrange EnsureVisualStudioHost(); var timestampService = await _fixture.GetDefaultTrustedTimestampServiceAsync(); using (var testContext = new ApexTestContext(VisualStudio, projectTemplate, XunitLogger)) using (var trustedCert = _fixture.TrustedRepositoryTestCertificate) using (var trustedExpiringTestCert = SigningTestUtility.GenerateTrustedTestCertificateThatExpiresIn5Seconds()) { XunitLogger.LogInformation("Creating package"); var package = CommonUtility.CreatePackage("ExpiredTestPackage", "1.0.0"); XunitLogger.LogInformation("Signing package"); var expiredTestPackage = CommonUtility.AuthorSignPackage(package, trustedExpiringTestCert.Source.Cert); await SimpleTestPackageUtility.CreatePackagesAsync(testContext.PackageSource, expiredTestPackage); var packageFullName = Path.Combine(testContext.PackageSource, expiredTestPackage.PackageName); XunitLogger.LogInformation("Waiting for package to expire"); SigningUtility.WaitForCertificateToExpire(trustedExpiringTestCert.Source.Cert); XunitLogger.LogInformation("Countersigning package"); var countersignedPackage = await SignedArchiveTestUtility.RepositorySignPackageAsync( new X509Certificate2(trustedCert.Source.Cert), packageFullName, testContext.PackageSource, new Uri("https://v3serviceIndexUrl.test/api/index.json"), timestampService.Url); File.Copy(countersignedPackage, packageFullName, overwrite: true); File.Delete(countersignedPackage); var nugetConsole = GetConsole(testContext.Project); nugetConsole.InstallPackageFromPMC(expiredTestPackage.Id, expiredTestPackage.Version); testContext.Project.Build(); testContext.NuGetApexTestService.WaitForAutoRestore(); // TODO: Fix bug where no warnings are shown when package is untrusted but still installed //nugetConsole.IsMessageFoundInPMC("expired certificate").Should().BeTrue("expired certificate warning"); CommonUtility.AssertPackageReferenceExists(VisualStudio, testContext.Project, expiredTestPackage.Id, expiredTestPackage.Version, XunitLogger); } }
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 VerifySignaturesAsync_SettingsRequireCheckCountersiganture_WithValidPrimarySignatureAndValidCountersignature_Succeeds() { // Arrange var nupkg = new SimpleTestPackageContext(); var timestampService = await _testFixture.GetDefaultTrustedTimestampServiceAsync(); var settings = new SignedPackageVerifierSettings( allowUnsigned: false, allowIllegal: false, allowUntrusted: false, allowIgnoreTimestamp: true, allowMultipleTimestamps: true, allowNoTimestamp: true, allowUnknownRevocation: true, alwaysVerifyCountersignature: true, allowNoClientCertificateList: true, allowNoRepositoryCertificateList: true); using (var dir = TestDirectory.Create()) using (var testCertificate = new X509Certificate2(_trustedTestCert.Source.Cert)) using (var repoTestCertificate = new X509Certificate2(_trustedTestCert.Source.Cert)) { var signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync( testCertificate, nupkg, dir, timestampService.Url); var countersignedPackagePath = await SignedArchiveTestUtility.RepositorySignPackageAsync(repoTestCertificate, signedPackagePath, dir, new Uri("https://v3serviceIndex.test/api/index.json"), timestampService.Url); var verifier = new PackageSignatureVerifier(_trustProviders); using (var packageReader = new PackageArchiveReader(countersignedPackagePath)) { // Act var result = await verifier.VerifySignaturesAsync(packageReader, settings, CancellationToken.None); var resultsWithErrors = result.Results.Where(r => r.GetErrorIssues().Any()); // Assert result.Valid.Should().BeTrue(); resultsWithErrors.Count().Should().Be(0); } } }
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 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 VerifySignaturesAsync_WithSignedTimestampedCountersignedAndCountersignatureTimestampedPackage_SucceedsAsync() { // Arrange var nupkg = new SimpleTestPackageContext(); TimestampService timestampService = await _testFixture.GetDefaultTrustedTimestampServiceAsync(); using (TestDirectory dir = TestDirectory.Create()) using (var testCertificate = new X509Certificate2(_trustedTestCert.Source.Cert)) using (TrustedTestCert <TestCertificate> trusted = SigningTestUtility.GenerateTrustedTestCertificate()) using (var counterCertificate = new X509Certificate2(trusted.Source.Cert)) { string signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync( testCertificate, nupkg, dir, timestampService.Url); string repositorySignedPackagePath = await SignedArchiveTestUtility.RepositorySignPackageAsync( counterCertificate, signedPackagePath, dir, TestServiceIndexUrl, timestampService.Url); var verifier = new PackageSignatureVerifier(_trustProviders); using (var packageReader = new PackageArchiveReader(repositorySignedPackagePath)) { // Act VerifySignaturesResult result = await verifier.VerifySignaturesAsync( packageReader, _verifyCommandSettings, CancellationToken.None); IEnumerable <PackageVerificationResult> resultsWithErrors = result.Results.Where(r => r.GetErrorIssues().Any()); // Assert result.IsValid.Should().BeTrue(); resultsWithErrors.Count().Should().Be(0); } } }
internal static async Task <Test> CreateAuthorSignedRepositoryCountersignedPackageAsync( X509Certificate2 authorCertificate, X509Certificate2 repositoryCertificate, Uri authorTimestampServiceUrl = null, Uri repoTimestampServiceUrl = null) { var directory = TestDirectory.Create(); using (var test = await CreateAuthorSignedPackageAsync(authorCertificate, authorTimestampServiceUrl)) { var signedPackagePath = await SignedArchiveTestUtility.RepositorySignPackageAsync( repositoryCertificate, test.PackageFile.FullName, directory, new Uri("https://nuget.test"), repoTimestampServiceUrl); return(new Test(directory, new FileInfo(signedPackagePath))); } }
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 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"); } }