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.");
                                    }
                                }
                            }
                    }
            }
        }
示例#2
0
        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);
                            }
                        }
            }
示例#4
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));
                    }
                }
        }
示例#5
0
        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);
                        }
                    }
        }
示例#6
0
        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);
                    }
                }
        }
示例#7
0
        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);
                }
        }
示例#8
0
            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)));
            }
示例#9
0
        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));
                        }
                    }
            }
示例#15
0
        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);
                        }
                    }
        }
示例#16
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);
                    }
                }
        }
示例#18
0
        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);
                            }
                    }
            }
        }
示例#21
0
        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);
                        }
                    }
            }
示例#23
0
        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);
                        }
                    }
                }
        }
示例#24
0
        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);
                }
        }
示例#25
0
        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));
                        }
                }
            }
示例#27
0
        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.");
            }
        }
示例#28
0
        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");
                    }
        }
示例#29
0
        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();
                        }
                }
        }