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 signedPackagePath = await SignedArchiveTestUtility.CreateSignedPackageAsync(testCertificate, nupkg, dir); var certificateFingerprint = CertificateUtility.GetHash(testCertificate, HashAlgorithmName.SHA256); var certificateFingerprintString = BitConverter.ToString(certificateFingerprint).Replace("-", ""); 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, SignedPackageVerifierSettings.Default); using (var packageReader = new PackageArchiveReader(signedPackagePath)) { // Act var result = await verifier.VerifySignaturesAsync(packageReader, CancellationToken.None); // Assert result.Valid.Should().BeTrue(); } } }
public async Task VerifySignaturesAsync_SettingsRequireTimestamp_NoTimestamp_Fails() { // Arrange var nupkg = new SimpleTestPackageContext(); var setting = new SignedPackageVerifierSettings( allowUnsigned: false, allowUntrusted: false, allowUntrustedSelfSignedCertificate: false, allowIgnoreTimestamp: false, allowMultipleTimestamps: true, allowNoTimestamp: false, allowUnknownRevocation: false); using (var dir = TestDirectory.Create()) using (var testCertificate = new X509Certificate2(_trustedTestCert.Source.Cert)) { var signedPackagePath = await SignedArchiveTestUtility.CreateSignedPackageAsync(testCertificate, nupkg, dir); var verifier = new PackageSignatureVerifier(_trustProviders, setting); 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 totalErrorIssues = resultsWithErrors.SelectMany(r => r.GetErrorIssues()); // Assert result.Valid.Should().BeFalse(); resultsWithErrors.Count().Should().Be(1); totalErrorIssues.Count().Should().Be(1); totalErrorIssues.First().Code.Should().Be(NuGetLogCode.NU3027); } } }
public async Task Signer_VerifyOnTamperedPackage_FileDeletedAsync(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.CreateSignedPackageAsync(testCertificate, nupkg, dir); SignedArchiveTestUtility.TamperWithPackage(signedPackagePath); var verifier = new PackageSignatureVerifier(_trustProviders, policy); 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 totalErrorIssues = resultsWithErrors.SelectMany(r => r.GetErrorIssues()); // Assert result.Valid.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 Signature_HasNoTimestamp() { // Arrange var nupkg = new SimpleTestPackageContext(); var testLogger = new TestLogger(); using (var dir = TestDirectory.Create()) using (var testCertificate = new X509Certificate2(_trustedTestCert.Source.Cert)) { // Act var signedPackagePath = await SignedArchiveTestUtility.CreateSignedPackageAsync(testCertificate, nupkg, dir); // Assert using (var stream = File.OpenRead(signedPackagePath)) using (var reader = new PackageArchiveReader(stream)) { var signatures = await reader.GetSignaturesAsync(CancellationToken.None); signatures.Count.Should().Be(1); var signature = signatures[0]; signature.Timestamps.Should().BeEmpty(); } } }
public async Task Load_WithReissuedSigningCertificate_Throws() { 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.CreateSignedPackageAsync( certificate1, packageContext, directory); using (var packageReader = new PackageArchiveReader(packageFilePath)) { var signature = (await packageReader.GetSignatureAsync(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>( () => Signature.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 Load_WithPrimarySignatureWithNoCertificates_Throws() { var packageContext = new SimpleTestPackageContext(); using (var directory = TestDirectory.Create()) using (var certificate = new X509Certificate2(_trustedTestCert.Source.Cert)) { var packageFilePath = await SignedArchiveTestUtility.CreateSignedPackageAsync( 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>( () => Signature.Load(signedCms)); Assert.Equal(NuGetLogCode.NU3010, exception.Code); Assert.Equal("The primary signature does not have a signing certificate.", exception.Message); } }
internal async Task AuthorSignAsync() { using (var request = new AuthorSignPackageRequest( new X509Certificate2(Certificate), HashAlgorithmName.SHA256, HashAlgorithmName.SHA256)) using (var originalPackage = new MemoryStream(Zip.ToByteArray(), writable: false)) using (var signedPackage = new MemoryStream()) { await SignedArchiveTestUtility.CreateSignedPackageAsync(request, originalPackage, signedPackage); SignedPackage = new MemoryStream(signedPackage.ToArray(), writable: false); } var isSigned = await SignedArchiveTestUtility.IsSignedAsync(SignedPackage); Assert.True(isSigned); }
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.CreateSignedPackageAsync(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, policy); 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 totalErrorIssues = resultsWithErrors.SelectMany(r => r.GetErrorIssues()); // Assert result.Valid.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 async Task RepositorySignAsync() { using (var request = new RepositorySignPackageRequest( new X509Certificate2(Certificate), HashAlgorithmName.SHA256, HashAlgorithmName.SHA256, new Uri("https://test.test"), packageOwners: null)) using (var originalPackage = new MemoryStream(Zip.ToByteArray(), writable: false)) using (var signedPackage = new MemoryStream()) { await SignedArchiveTestUtility.CreateSignedPackageAsync(request, originalPackage, signedPackage); SignedPackage = new MemoryStream(signedPackage.ToArray(), writable: false); } var isSigned = await SignedArchiveTestUtility.IsSignedAsync(SignedPackage); Assert.True(isSigned); }
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.CreateSignedPackageAsync(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, policy); 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 totalErrorIssues = resultsWithErrors.SelectMany(r => r.GetErrorIssues()); // Assert result.Valid.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 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.CreateSignedPackageAsync(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, policy); 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 totalErrorIssues = resultsWithErrors.SelectMany(r => r.GetErrorIssues()); // Assert result.Valid.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.CreateSignedPackageAsync( 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 Signer_VerifyOnSignedPackageAsync(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.CreateSignedPackageAsync(testCertificate, nupkg, dir); var verifier = new PackageSignatureVerifier(_trustProviders, policy); using (var packageReader = new PackageArchiveReader(signedPackagePath)) { // Act var result = await verifier.VerifySignaturesAsync(packageReader, CancellationToken.None); // Assert result.Valid.Should().BeTrue(); } } }
public async Task GetTrustResultAsync_VerifyWithoutCertificateInAllowList_Fail() { // Arrange var nupkg = new SimpleTestPackageContext(); using (var dir = TestDirectory.Create()) using (var testCertificate = new X509Certificate2(_trustedTestCert.Source.Cert)) { var signedPackagePath = await SignedArchiveTestUtility.CreateSignedPackageAsync(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 verifier = new PackageSignatureVerifier(trustProviders, SignedPackageVerifierSettings.Default); 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 totalErrorIssues = resultsWithErrors.SelectMany(r => r.GetErrorIssues()); // Assert result.Valid.Should().BeFalse(); resultsWithErrors.Count().Should().Be(1); totalErrorIssues.Count().Should().Be(1); totalErrorIssues.First().Code.Should().Be(NuGetLogCode.NU3003); totalErrorIssues.First().Message.Should().Contain(_noCertInAllowList); } } }
public async Task VerifySignaturesAsync_ValidCertificate_Success() { // Arrange var nupkg = new SimpleTestPackageContext(); using (var dir = TestDirectory.Create()) using (var testCertificate = new X509Certificate2(_trustedTestCert.Source.Cert)) { var signedPackagePath = await SignedArchiveTestUtility.CreateSignedPackageAsync(testCertificate, nupkg, dir); var verifier = new PackageSignatureVerifier(_trustProviders, SignedPackageVerifierSettings.VerifyCommandDefaultPolicy); using (var packageReader = new PackageArchiveReader(signedPackagePath)) { // Act var result = await verifier.VerifySignaturesAsync(packageReader, CancellationToken.None); var resultsWithErrors = result.Results.Where(r => r.GetErrorIssues().Any()); // Assert result.Valid.Should().BeTrue(); resultsWithErrors.Count().Should().Be(0); } } }