public async Task GetTimestampCertificateChain_WithValidSigningCertificateUsage_ReturnsChain( SigningCertificateUsage signingCertificateUsage) { ISigningTestServer testServer = await _fixture.GetSigningTestServerAsync(); CertificateAuthority rootCa = await _fixture.GetDefaultTrustedCertificateAuthorityAsync(); var options = new TimestampServiceOptions() { SigningCertificateUsage = signingCertificateUsage }; TimestampService timestampService = TimestampService.Create(rootCa, options); using (testServer.RegisterResponder(timestampService)) { var nupkg = new SimpleTestPackageContext(); using (var certificate = new X509Certificate2(_fixture.TrustedTestCertificate.Source.Cert)) using (var directory = TestDirectory.Create()) { var signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync( certificate, nupkg, directory, timestampService.Url); using (FileStream stream = File.OpenRead(signedPackagePath)) using (var reader = new PackageArchiveReader(stream)) { PrimarySignature signature = await reader.GetPrimarySignatureAsync(CancellationToken.None); using (IX509CertificateChain actualChain = SignatureUtility.GetTimestampCertificateChain(signature)) { Assert.NotEmpty(actualChain); IReadOnlyList <Org.BouncyCastle.X509.X509Certificate> expectedChain = GetExpectedCertificateChain(timestampService); Assert.Equal(expectedChain.Count, actualChain.Count); for (var i = 0; i < expectedChain.Count; ++i) { Org.BouncyCastle.X509.X509Certificate expectedCertificate = expectedChain[i]; X509Certificate2 actualCertificate = actualChain[i]; Assert.True( expectedCertificate.GetEncoded().SequenceEqual(actualCertificate.RawData), $"The certificate at index {i} in the chain is unexpected."); } } } } } }
public async Task Restore_TamperedPackage_FailsAsync() { // Arrange using (var pathContext = new SimpleTestPathContext()) using (var testCertificate = new X509Certificate2(_trustedTestCert.Source.Cert)) { // Set up solution, project, and packages var solution = new SimpleTestSolutionContext(pathContext.SolutionRoot); var projectA = SimpleTestProjectContext.CreateNETCore( "a", pathContext.SolutionRoot, NuGetFramework.Parse("NETStandard2.0")); var packageX = new SimpleTestPackageContext("X", "9.0.0"); var signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync(testCertificate, packageX, pathContext.PackageSource); SignedArchiveTestUtility.TamperWithPackage(signedPackagePath); projectA.AddPackageToAllFrameworks(packageX); solution.Projects.Add(projectA); solution.Create(pathContext.SolutionRoot); var args = new string[] { projectA.ProjectPath, "-Source", pathContext.PackageSource }; // Act var result = RunRestore(_nugetExePath, pathContext, expectedExitCode: 1, additionalArgs: args); var reader = new LockFileFormat(); var lockFile = reader.Read(projectA.AssetsFileOutputPath); var errors = lockFile.LogMessages.Where(m => m.Level == LogLevel.Error); var warnings = lockFile.LogMessages.Where(m => m.Level == LogLevel.Warning); // Assert result.ExitCode.Should().Be(1); result.Errors.Should().Contain(string.Format(_NU3008, SigningTestUtility.AddSignatureLogPrefix(_NU3008Message, packageX.Identity, pathContext.PackageSource))); result.AllOutput.Should().Contain($"WARNING: {string.Format(_NU3027, SigningTestUtility.AddSignatureLogPrefix(_NU3027Message, packageX.Identity, pathContext.PackageSource))}"); errors.Count().Should().Be(1); errors.First().Code.Should().Be(NuGetLogCode.NU3008); errors.First().Message.Should().Be(SigningTestUtility.AddSignatureLogPrefix(_NU3008Message, packageX.Identity, pathContext.PackageSource)); errors.First().LibraryId.Should().Be(packageX.Id); warnings.Count().Should().Be(1); warnings.First().Code.Should().Be(NuGetLogCode.NU3027); warnings.First().Message.Should().Be(SigningTestUtility.AddSignatureLogPrefix(_NU3027Message, packageX.Identity, pathContext.PackageSource)); warnings.First().LibraryId.Should().Be(packageX.Id); } }
public async Task VerifySignaturesAsync_SettingsRequireCheckCountersignature_WithValidPrimarySignatureAndValidCountersignature_SucceedsAsync() { // 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.IfExistsAndIsNecessary, revocationMode: RevocationMode.Online); using (TestDirectory dir = TestDirectory.Create()) using (var testCertificate = new X509Certificate2(_trustedTestCert.Source.Cert)) using (var repoTestCertificate = new X509Certificate2(_trustedTestCert.Source.Cert)) { string signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync( testCertificate, nupkg, dir, timestampService.Url); 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().BeTrue(); resultsWithErrors.Count().Should().Be(0); } } }
public async Task VerifySignaturesAsync_ExpiredCertificateAndTimestamp_Success() { var ca = await _testFixture.GetDefaultTrustedCertificateAuthorityAsync(); var timestampService = await _testFixture.GetDefaultTrustedTimestampServiceAsync(); var keyPair = SigningTestUtility.GenerateKeyPair(publicKeyLength: 2048); var 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") }; var bcCertificate = ca.IssueCertificate(issueOptions); using (var certificate = new X509Certificate2(bcCertificate.GetEncoded())) using (var directory = TestDirectory.Create()) { certificate.PrivateKey = DotNetUtilities.ToRSA(keyPair.Private as RsaPrivateCrtKeyParameters); var notAfter = certificate.NotAfter.ToUniversalTime(); var packageContext = new SimpleTestPackageContext(); var signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync( certificate, packageContext, directory, timestampService.Url); var waitDuration = (notAfter - DateTimeOffset.UtcNow).Add(TimeSpan.FromSeconds(1)); // Wait for the certificate to expire. Trust of the signature will require a valid timestamp. await Task.Delay(waitDuration); Assert.True(DateTime.UtcNow > notAfter); var verifier = new PackageSignatureVerifier(_trustProviders); using (var packageReader = new PackageArchiveReader(signedPackagePath)) { var result = await verifier.VerifySignaturesAsync(packageReader, _verifyCommandSettings, CancellationToken.None); var trustProvider = result.Results.Single(); Assert.True(result.Valid); 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 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 GetTrustResultAsync_VerifyWithoutCertificateInAllowListWithAllowUntrusted_Warn() { // Arrange var nupkg = new SimpleTestPackageContext(); using (var dir = TestDirectory.Create()) using (var testCertificate = new X509Certificate2(_trustedTestCert.Source.Cert)) { var signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync(testCertificate, nupkg, dir); var allowListHashes = new[] { "abc" }; var allowList = allowListHashes.Select(hash => new CertificateHashAllowListEntry(VerificationTarget.Primary, hash)).ToList(); var trustProviders = new[] { new AllowListVerificationProvider(allowList) }; var settings = new SignedPackageVerifierSettings( allowUnsigned: false, allowIllegal: false, allowUntrusted: true, allowUntrustedSelfIssuedCertificate: true, allowIgnoreTimestamp: true, allowMultipleTimestamps: true, allowNoTimestamp: true, allowUnknownRevocation: true); var verifier = new PackageSignatureVerifier(trustProviders, settings); using (var packageReader = new PackageArchiveReader(signedPackagePath)) { // Act var result = await verifier.VerifySignaturesAsync(packageReader, CancellationToken.None); var resultsWithErrors = result.Results.Where(r => r.GetErrorIssues().Any()); var resultsWithWarnings = result.Results.Where(r => r.GetWarningIssues().Any()); var totalErrorIssues = resultsWithErrors.SelectMany(r => r.GetErrorIssues()); var totalWarningIssues = resultsWithWarnings.SelectMany(r => r.GetWarningIssues()); // Assert result.Valid.Should().BeTrue(); resultsWithErrors.Count().Should().Be(0); resultsWithWarnings.Count().Should().Be(1); totalErrorIssues.Count().Should().Be(0); totalWarningIssues.Count().Should().Be(1); totalWarningIssues.First().Code.Should().Be(NuGetLogCode.NU3003); totalWarningIssues.First().Message.Should().Contain(_noCertInAllowList); } } }
public async Task Restore_TamperedPackageInPackagesConfig_FailsWithErrorAsync() { // Arrange var nupkg = new SimpleTestPackageContext("A", "1.0.0"); var packagesConfigContent = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<packages>" + " <package id=\"X\" version=\"9.0.0\" targetFramework=\"net461\" />" + "</packages>"; using (var pathContext = new SimpleTestPathContext()) using (var testCertificate = new X509Certificate2(_trustedTestCert.Source.Cert)) { // Set up solution, project, and packages var solution = new SimpleTestSolutionContext(pathContext.SolutionRoot); var projectA = new SimpleTestProjectContext( "a", ProjectStyle.PackagesConfig, pathContext.SolutionRoot); var packageX = new SimpleTestPackageContext("X", "9.0.0"); var signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync(testCertificate, packageX, pathContext.PackageSource); SignedArchiveTestUtility.TamperWithPackage(signedPackagePath); projectA.AddPackageToAllFrameworks(packageX); solution.Projects.Add(projectA); solution.Create(pathContext.SolutionRoot); var packagesConfigPath = Path.Combine(Directory.GetParent(projectA.ProjectPath).FullName, "packages.config"); File.WriteAllBytes(packagesConfigPath, Encoding.ASCII.GetBytes(packagesConfigContent)); var args = new string[] { projectA.ProjectPath, "-Source", pathContext.PackageSource, "-PackagesDirectory", "./packages" }; // Act var result = RunRestore(_nugetExePath, pathContext, expectedExitCode: 1, additionalArgs: args); // Assert result.ExitCode.Should().Be(1); result.Errors.Should().Contain(_NU3008); result.AllOutput.Should().Contain(_NU3027); } }
internal static async Task <Test> CreateAuthorSignedPackageAsync( X509Certificate2 certificate, Uri timestampServiceUrl = null) { var packageContext = new SimpleTestPackageContext(); var directory = TestDirectory.Create(); var signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync( certificate, packageContext, directory, timestampServiceUrl); return(new Test(directory, new FileInfo(signedPackagePath))); }
public async Task Install_TamperedAndRevokedCertificateSignaturePackage_FailsAsync() { // Arrange var nupkg = new SimpleTestPackageContext("A", "1.0.0"); var testServer = await _testFixture.GetSigningTestServerAsync(); var certificateAuthority = await _testFixture.GetDefaultTrustedCertificateAuthorityAsync(); var issueOptions = IssueCertificateOptions.CreateDefaultForEndCertificate(); var bcCertificate = certificateAuthority.IssueCertificate(issueOptions); using (var context = new SimpleTestPathContext()) using (var testCertificate = new X509Certificate2(bcCertificate.GetEncoded())) { testCertificate.PrivateKey = DotNetUtilities.ToRSA(issueOptions.KeyPair.Private as RsaPrivateCrtKeyParameters); var signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync(testCertificate, nupkg, context.WorkingDirectory); SignedArchiveTestUtility.TamperWithPackage(signedPackagePath); await certificateAuthority.OcspResponder.WaitForResponseExpirationAsync(bcCertificate); certificateAuthority.Revoke( bcCertificate, RevocationReason.KeyCompromise, DateTimeOffset.UtcNow.AddSeconds(-1)); 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: 1, additionalArgs: args); // Assert result.ExitCode.Should().Be(1); result.Errors.Should().Contain(string.Format(_NU3008, SigningTestUtility.AddSignatureLogPrefix(_NU3008Message, nupkg.Identity, context.WorkingDirectory))); result.Errors.Should().Contain(string.Format(_NU3012, SigningTestUtility.AddSignatureLogPrefix(_NU3012Message, nupkg.Identity, context.WorkingDirectory))); result.AllOutput.Should().Contain($"WARNING: {string.Format(_NU3027, SigningTestUtility.AddSignatureLogPrefix(_NU3027Message, nupkg.Identity, context.WorkingDirectory))}"); } }
public async Task Load_WithReissuedSigningCertificate_ThrowsAsync() { var certificates = _testFixture.TrustedTestCertificateWithReissuedCertificate; var packageContext = new SimpleTestPackageContext(); using (var directory = TestDirectory.Create()) using (var certificate1 = new X509Certificate2(certificates[0].Source.Cert)) using (var certificate2 = new X509Certificate2(certificates[1].Source.Cert)) { var packageFilePath = await SignedArchiveTestUtility.AuthorSignPackageAsync( certificate1, packageContext, directory); using (var packageReader = new PackageArchiveReader(packageFilePath)) { var signature = (await packageReader.GetPrimarySignatureAsync(CancellationToken.None)); var certificateStore = X509StoreFactory.Create( "Certificate/Collection", new X509CollectionStoreParameters( new[] { Org.BouncyCastle.Security.DotNetUtilities.FromX509Certificate(certificate2) })); var emptyCertificateStore = X509StoreFactory.Create( "Certificate/Collection", new X509CollectionStoreParameters(Array.Empty <Org.BouncyCastle.X509.X509Certificate>())); var crlStore = X509StoreFactory.Create( "CRL/Collection", new X509CollectionStoreParameters(Array.Empty <Org.BouncyCastle.X509.X509Crl>())); var bytes = signature.SignedCms.Encode(); using (var readStream = new MemoryStream(bytes)) using (var writeStream = new MemoryStream()) { CmsSignedDataParser.ReplaceCertificatesAndCrls( readStream, certificateStore, crlStore, emptyCertificateStore, writeStream); var exception = Assert.Throws <SignatureException>( () => PrimarySignature.Load(writeStream.ToArray())); Assert.Equal(NuGetLogCode.NU3011, exception.Code); Assert.Equal("A certificate referenced by the signing-certificate-v2 attribute could not be found.", exception.Message); } } } }
public async Task GetTrustResultAsync_VerifyWithoutCertificateInRepoAllowList_ErrorsWhenNotAllowUntrustedAsync() { // Arrange var nupkg = new SimpleTestPackageContext(); using (var dir = TestDirectory.Create()) using (var testCertificate = new X509Certificate2(_trustedTestCert.Source.Cert)) { var signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync(testCertificate, nupkg, dir); var allowListHashes = new[] { "abc" }; var allowList = allowListHashes.Select(hash => new CertificateHashAllowListEntry(VerificationTarget.Primary, hash, HashAlgorithmName.SHA256)).ToList(); var trustProviders = new[] { new AllowListVerificationProvider() }; var verifier = new PackageSignatureVerifier(trustProviders); var verifierSettings = GetSettings( allowUnsigned: false, allowUntrusted: false, clientAllowList: null, repoAllowList: allowList); using (var packageReader = new PackageArchiveReader(signedPackagePath)) { // Act var result = await verifier.VerifySignaturesAsync(packageReader, verifierSettings, CancellationToken.None); var resultsWithErrors = result.Results.Where(r => r.GetErrorIssues().Any()); var resultsWithWarnings = result.Results.Where(r => r.GetWarningIssues().Any()); var totalErrorIssues = resultsWithErrors.SelectMany(r => r.GetErrorIssues()); var totalWarningIssues = resultsWithWarnings.SelectMany(r => r.GetWarningIssues()); // Assert result.Valid.Should().BeFalse(); resultsWithErrors.Count().Should().Be(1); resultsWithWarnings.Count().Should().Be(0); totalErrorIssues.Count().Should().Be(1); totalWarningIssues.Count().Should().Be(0); totalErrorIssues.First().Code.Should().Be(NuGetLogCode.NU3034); totalErrorIssues.First().Message.Should().Be(_noMatchInRepoAllowList); } } }
public async Task Load_WithPrimarySignatureWithNoCertificates_ThrowsAsync() { var packageContext = new SimpleTestPackageContext(); using (var directory = TestDirectory.Create()) using (var certificate = new X509Certificate2(_trustedTestCert.Source.Cert)) { var packageFilePath = await SignedArchiveTestUtility.AuthorSignPackageAsync( certificate, packageContext, directory); var signatureFileBytes = ReadSignatureFile(packageFilePath); var signedCms = new SignedCms(); signedCms.Decode(signatureFileBytes); var certificateStore = X509StoreFactory.Create( "Certificate/Collection", new X509CollectionStoreParameters(Array.Empty <Org.BouncyCastle.X509.X509Certificate>())); var crlStore = X509StoreFactory.Create( "CRL/Collection", new X509CollectionStoreParameters(Array.Empty <Org.BouncyCastle.X509.X509Crl>())); using (var readStream = new MemoryStream(signedCms.Encode())) using (var writeStream = new MemoryStream()) { CmsSignedDataParser.ReplaceCertificatesAndCrls( readStream, certificateStore, crlStore, certificateStore, writeStream); signedCms.Decode(writeStream.ToArray()); } Assert.Empty(signedCms.Certificates); var exception = Assert.Throws <SignatureException>( () => PrimarySignature.Load(signedCms)); Assert.Equal(NuGetLogCode.NU3010, exception.Code); Assert.Contains("The primary signature does not have a signing certificate.", exception.Message); } }
public async Task TrustedSignersCommand_AddTrustedSigner_WithAuthorSignedPackage_AddsItSuccesfullyToConfigAsync(bool allowUntrustedRoot) { // Arrange var nugetConfigFileName = "NuGet.Config"; var config = @"<?xml version=""1.0"" encoding=""utf-8""?> <configuration> </configuration>"; // Arrange var package = new SimpleTestPackageContext(); using (var dir = TestDirectory.Create()) using (var zipStream = await package.CreateAsStreamAsync()) using (var trustedTestCert = SigningTestUtility.GenerateTrustedTestCertificate()) { var certFingerprint = SignatureTestUtility.GetFingerprint(trustedTestCert.Source.Cert, HashAlgorithmName.SHA256); var signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync(trustedTestCert.Source.Cert, package, dir); SettingsTestUtils.CreateConfigurationFile(nugetConfigFileName, dir, config); var nugetConfigPath = Path.Combine(dir, nugetConfigFileName); var allowUntrustedRootArg = allowUntrustedRoot ? "-AllowUntrustedRoot" : string.Empty; // Act var commandResult = CommandRunner.Run( _nugetExePath, dir, $"trusted-signers add {signedPackagePath} -Name signer -Author {allowUntrustedRootArg} -Config {nugetConfigPath}", waitForExit: true); // Assert commandResult.Success.Should().BeTrue(); commandResult.AllOutput.Should().Contain(string.Format(CultureInfo.CurrentCulture, _successfulAddTrustedSigner, "author", "signer")); var expectedResult = SettingsTestUtils.RemoveWhitespace($@"<?xml version=""1.0"" encoding=""utf-8""?> <configuration> <trustedSigners> <author name=""signer""> <certificate fingerprint=""{certFingerprint}"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""{allowUntrustedRoot.ToString().ToLower()}"" /> </author> </trustedSigners> </configuration>"); SettingsTestUtils.RemoveWhitespace(File.ReadAllText(nugetConfigPath)).Should().Be(expectedResult); } }
public 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 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 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 GetTrustResultAsync_VerifyWithEmptyRepositoryAndClientCertificateAllowList_ErrorsWhenRequiredAndNotAllowUntrustedAsync() { // Arrange var nupkg = new SimpleTestPackageContext(); using (var dir = TestDirectory.Create()) using (var testCertificate = new X509Certificate2(_trustedTestCert.Source.Cert)) { var signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync(testCertificate, nupkg, dir); var trustProviders = new[] { new AllowListVerificationProvider() }; var verifier = new PackageSignatureVerifier(trustProviders); var verifierSettings = GetSettings( allowUnsigned: true, allowUntrusted: false, allowNoClientCertificateList: false, allowNoRepositoryCertificateList: false, clientAllowList: new List <CertificateHashAllowListEntry>(), repoAllowList: new List <CertificateHashAllowListEntry>()); using (var packageReader = new PackageArchiveReader(signedPackagePath)) { // Act var result = await verifier.VerifySignaturesAsync(packageReader, verifierSettings, CancellationToken.None); var resultsWithErrors = result.Results.Where(r => r.GetErrorIssues().Any()); var totalErrorIssues = resultsWithErrors.SelectMany(r => r.GetErrorIssues()).ToList(); // Assert result.Valid.Should().BeFalse(); resultsWithErrors.Count().Should().Be(1); totalErrorIssues.Count().Should().Be(2); totalErrorIssues[0].Code.Should().Be(NuGetLogCode.NU3034); totalErrorIssues[0].Message.Should().Be(_noClientAllowList); totalErrorIssues[1].Code.Should().Be(NuGetLogCode.NU3034); totalErrorIssues[1].Message.Should().Be(_noRepoAllowList); } } }
public async Task DotnetTrust_AuthorAction_AbsolutePathConfileFile_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> </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(); resultAdd.AllOutput.Should().Contain(string.Format(CultureInfo.CurrentCulture, _successfulAddTrustedSigner, "author", "nuget")); string expectedResult = SettingsTestUtils.RemoveWhitespace($@"<?xml version=""1.0"" encoding=""utf-8""?> <configuration> < 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 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); } } }
public async Task GetTimestampCertificateChain_WithShortEssCertIdCertificateHash_Throws( SigningCertificateUsage signingCertificateUsage) { ISigningTestServer testServer = await _fixture.GetSigningTestServerAsync(); CertificateAuthority rootCa = await _fixture.GetDefaultTrustedCertificateAuthorityAsync(); var options = new TimestampServiceOptions() { SigningCertificateUsage = signingCertificateUsage, SigningCertificateV1Hash = new byte[SHA1HashLength - 1] }; TimestampService timestampService = TimestampService.Create(rootCa, options); using (testServer.RegisterResponder(timestampService)) { var nupkg = new SimpleTestPackageContext(); using (var certificate = new X509Certificate2(_fixture.TrustedTestCertificate.Source.Cert)) using (var directory = TestDirectory.Create()) { var signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync( certificate, nupkg, directory, timestampService.Url); using (FileStream stream = File.OpenRead(signedPackagePath)) using (var reader = new PackageArchiveReader(stream)) { PrimarySignature signature = await reader.GetPrimarySignatureAsync(CancellationToken.None); var exception = Assert.Throws <SignatureException>( () => SignatureUtility.GetTimestampCertificateChain(signature)); Assert.Equal( "A certificate referenced by the signing-certificate attribute could not be found.", exception.Message); } } } }
public async Task Signer_VerifyOnTamperedPackage_FileAddedAsync(string policyString) { // Arrange var nupkg = new SimpleTestPackageContext(); var policy = GetSettingsPolicy(policyString); var newEntryData = "malicious code"; var newEntryName = "malicious file"; using (var dir = TestDirectory.Create()) using (var testCertificate = new X509Certificate2(_trustedTestCert.Source.Cert)) { var signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync(testCertificate, nupkg, dir); // tamper with the package using (var stream = File.Open(signedPackagePath, FileMode.Open)) using (var zip = new ZipArchive(stream, ZipArchiveMode.Update)) using (var newEntryStream = zip.CreateEntry(newEntryName).Open()) using (var newEntryDataStream = new MemoryStream(Encoding.UTF8.GetBytes(newEntryData))) { newEntryStream.Seek(offset: 0, origin: SeekOrigin.End); newEntryDataStream.CopyTo(newEntryStream); } var verifier = new PackageSignatureVerifier(_trustProviders); using (var packageReader = new PackageArchiveReader(signedPackagePath)) { // Act var result = await verifier.VerifySignaturesAsync(packageReader, policy, CancellationToken.None); var resultsWithErrors = result.Results.Where(r => r.GetErrorIssues().Any()); var totalErrorIssues = resultsWithErrors.SelectMany(r => r.GetErrorIssues()); // Assert result.IsValid.Should().BeFalse(); resultsWithErrors.Count().Should().Be(1); totalErrorIssues.Count().Should().Be(1); totalErrorIssues.First().Code.Should().Be(NuGetLogCode.NU3008); totalErrorIssues.First().Message.Should().Be(_packageTamperedError); } } }
public async Task VerifySignaturesAsync_SettingsRequireTimestamp_NoTimestamp_FailsAsync() { // Arrange var nupkg = new SimpleTestPackageContext(); var settings = new SignedPackageVerifierSettings( allowUnsigned: false, allowIllegal: false, allowUntrusted: false, allowIgnoreTimestamp: false, allowMultipleTimestamps: true, allowNoTimestamp: false, allowUnknownRevocation: false, reportUnknownRevocation: true, verificationTarget: VerificationTarget.All, signaturePlacement: SignaturePlacement.Any, repositoryCountersignatureVerificationBehavior: SignatureVerificationBehavior.IfExistsAndIsNecessary, revocationMode: RevocationMode.Online); using (TestDirectory dir = TestDirectory.Create()) using (var testCertificate = new X509Certificate2(_trustedTestCert.Source.Cert)) { string signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync(testCertificate, nupkg, dir); var verifier = new PackageSignatureVerifier(_trustProviders); using (var packageReader = new PackageArchiveReader(signedPackagePath)) { // Act VerifySignaturesResult result = await verifier.VerifySignaturesAsync(packageReader, settings, CancellationToken.None); IEnumerable <PackageVerificationResult> resultsWithErrors = result.Results.Where(r => r.GetErrorIssues().Any()); IEnumerable <ILogMessage> totalErrorIssues = resultsWithErrors.SelectMany(r => r.GetErrorIssues()); // Assert result.IsValid.Should().BeFalse(); resultsWithErrors.Count().Should().Be(1); totalErrorIssues.Count().Should().Be(1); totalErrorIssues.First().Code.Should().Be(NuGetLogCode.NU3027); } } }
public async Task Signer_VerifyOnTamperedPackage_SignatureRemovedAsync(string policyString, bool expectedValidity) { // Arrange var nupkg = new SimpleTestPackageContext(); var policy = GetSettingsPolicy(policyString); using (var dir = TestDirectory.Create()) using (var testCertificate = new X509Certificate2(_trustedTestCert.Source.Cert)) { var signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync(testCertificate, nupkg, dir); // unsign the package using (var stream = File.Open(signedPackagePath, FileMode.Open)) using (var zip = new ZipArchive(stream, ZipArchiveMode.Update)) { var entry = zip.GetEntry(SigningSpecifications.V1.SignaturePath); entry.Delete(); } var verifier = new PackageSignatureVerifier(_trustProviders); using (var packageReader = new PackageArchiveReader(signedPackagePath)) { // Act var result = await verifier.VerifySignaturesAsync(packageReader, policy, CancellationToken.None); var resultsWithErrors = result.Results.Where(r => r.GetErrorIssues().Any()); var totalErrorIssues = resultsWithErrors.SelectMany(r => r.GetErrorIssues()); // Assert result.IsValid.Should().Be(expectedValidity); if (!expectedValidity) { resultsWithErrors.Count().Should().Be(1); totalErrorIssues.Count().Should().Be(1); totalErrorIssues.First().Code.Should().Be(NuGetLogCode.NU3004); totalErrorIssues.First().Message.Should().Be(_packageUnsignedError); } } } }
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 Signer_VerifyOnTamperedPackage_FileMetadataModifiedAsync(string policyString) { // Arrange var nupkg = new SimpleTestPackageContext(); var policy = GetSettingsPolicy(policyString); using (var dir = TestDirectory.Create()) using (var testCertificate = new X509Certificate2(_trustedTestCert.Source.Cert)) { var signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync(testCertificate, nupkg, dir); // tamper with the package using (var stream = File.Open(signedPackagePath, FileMode.Open)) using (var zip = new ZipArchive(stream, ZipArchiveMode.Update)) { var entry = zip.Entries.First(); // ZipArchiveEntry.LastWriteTime supports a resolution of two seconds. // https://msdn.microsoft.com/en-us/library/system.io.compression.ziparchiveentry.lastwritetime(v=vs.110).aspx entry.LastWriteTime = entry.LastWriteTime.AddSeconds(2); } var verifier = new PackageSignatureVerifier(_trustProviders); using (var packageReader = new PackageArchiveReader(signedPackagePath)) { // Act var result = await verifier.VerifySignaturesAsync(packageReader, policy, CancellationToken.None); var resultsWithErrors = result.Results.Where(r => r.GetErrorIssues().Any()); var totalErrorIssues = resultsWithErrors.SelectMany(r => r.GetErrorIssues()); // Assert result.IsValid.Should().BeFalse(); resultsWithErrors.Count().Should().Be(1); totalErrorIssues.Count().Should().Be(1); totalErrorIssues.First().Code.Should().Be(NuGetLogCode.NU3008); totalErrorIssues.First().Message.Should().Be(_packageTamperedError); } } }
internal static async Task <Test> CreateWithoutRepositoryCountersignatureAsync( X509Certificate2 certificate) { var packageContext = new SimpleTestPackageContext(); using (var directory = TestDirectory.Create()) { var signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync( certificate, packageContext, directory); using (var stream = File.OpenRead(signedPackagePath)) using (var reader = new PackageArchiveReader(stream)) { var primarySignature = await reader.GetPrimarySignatureAsync(CancellationToken.None); return(new Test(request: null, primarySignature: primarySignature)); } } }
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 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 Signature_HasNoTimestampAsync() { // Arrange var nupkg = new SimpleTestPackageContext(); using (var dir = TestDirectory.Create()) using (var testCertificate = new X509Certificate2(_trustedTestCert.Source.Cert)) { // Act var signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync(testCertificate, nupkg, dir); // Assert using (var stream = File.OpenRead(signedPackagePath)) using (var reader = new PackageArchiveReader(stream)) { var signature = await reader.GetPrimarySignatureAsync(CancellationToken.None); signature.Should().NotBeNull(); signature.Timestamps.Should().BeEmpty(); } } }