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);
                    }
                }
        }
示例#4
0
        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();
                        }
                }
        }
示例#5
0
        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);
                                }
                        }
                    }
        }
示例#6
0
        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);
                    }
                }
        }