public async Task StripsAndRejectsPackagesWithRepositorySignatureWhenPackageMustBeAuthorSigned()
            {
                _packageStream = TestResources.GetResourceStream(TestResources.RepoSignedPackageLeaf1);
                TestUtility.RequireSignedPackage(_corePackageService, TestResources.RepoSignedPackageLeafId);
                _message = new SignatureValidationMessage(
                    TestResources.RepoSignedPackageLeafId,
                    TestResources.RepoSignedPackageLeaf1Version,
                    new Uri($"https://unit.test/{TestResources.RepoSignedPackageLeaf1.ToLowerInvariant()}"),
                    Guid.NewGuid());

                Stream uploadedStream = null;

                _packageFileService
                .Setup(x => x.SaveAsync(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <Guid>(), It.IsAny <Stream>()))
                .Returns(Task.CompletedTask)
                .Callback <string, string, Guid, Stream>((_, __, ___, s) => uploadedStream = s);

                var result = await _target.ValidateAsync(
                    _packageKey,
                    _packageStream,
                    _message,
                    _cancellationToken);

                Validate(result, ValidationStatus.Failed, PackageSigningStatus.Invalid);
                Assert.Equal(1, result.Issues.Count);
                var issue = Assert.IsType <NoDataValidationIssue>(result.Issues[0]);

                Assert.Equal(ValidationIssueCode.PackageIsNotSigned, issue.IssueCode);
            }
            public async Task RejectsSignedPackagesWithKnownCertificatesButFailedFullVerifyResult()
            {
                // Arrange
                _packageStream = TestResources.GetResourceStream(TestResources.SignedPackageLeaf1);
                TestUtility.RequireSignedPackage(
                    _corePackageService,
                    TestResources.SignedPackageLeafId,
                    TestResources.Leaf1Thumbprint);
                _fullVerifyResult = new VerifySignaturesResult(valid: false);
                _message          = new SignatureValidationMessage(
                    TestResources.SignedPackageLeafId,
                    TestResources.SignedPackageLeaf1Version,
                    new Uri($"https://unit.test/{TestResources.SignedPackageLeaf1.ToLowerInvariant()}"),
                    Guid.NewGuid());

                // Act
                var result = await _target.ValidateAsync(
                    _packageKey,
                    _packageStream,
                    _message,
                    _cancellationToken);

                // Assert
                Validate(result, ValidationStatus.Failed, PackageSigningStatus.Invalid);
                Assert.Empty(result.Issues);
            }
Exemple #3
0
            public async Task AcceptsRepositorySignedPackage()
            {
                // Arrange
                _configuration.AllowedRepositorySigningCertificates = new List <string> {
                    TestResources.Leaf1Thumbprint
                };
                _packageStream = TestResources.GetResourceStream(TestResources.RepoSignedPackageLeaf1);

                TestUtility.RequireUnsignedPackage(_corePackageService, TestResources.RepoSignedPackageLeafId, TestResources.RepoSignedPackageLeaf1Version);

                _message = new SignatureValidationMessage(
                    TestResources.RepoSignedPackageLeafId,
                    TestResources.RepoSignedPackageLeaf1Version,
                    new Uri($"https://unit.test/{TestResources.RepoSignedPackageLeaf1.ToLowerInvariant()}"),
                    Guid.NewGuid());

                // Act
                var result = await _target.ValidateAsync(
                    _packageKey,
                    _packageStream,
                    _message,
                    _cancellationToken);

                // Assert
                Validate(result, ValidationStatus.Succeeded, PackageSigningStatus.Valid);
                Assert.Empty(result.Issues);
            }
Exemple #4
0
            public async Task WhenRepositorySigningIsRequired_FailsValidationOfPackageWhoseRepositorySignatureIsStripped(
                string resourceName,
                string packageId,
                string packageVersion,
                PackageSigningStatus signingStatus,
                bool allowSignedPackage)
            {
                // Arrange
                _packageStream = TestResources.GetResourceStream(resourceName);
                if (allowSignedPackage)
                {
                    TestUtility.RequireSignedPackage(_corePackageService, packageId, packageVersion, TestResources.Leaf1Thumbprint);
                }
                else
                {
                    TestUtility.RequireUnsignedPackage(_corePackageService, packageId, packageVersion);
                }
                _message = new SignatureValidationMessage(
                    packageId,
                    packageVersion,
                    new Uri($"https://unit.test/{TestResources.RepoSignedPackageLeafId.ToLowerInvariant()}"),
                    Guid.NewGuid(),
                    requireRepositorySignature: true);

                // Act
                var result = await _target.ValidateAsync(
                    _packageKey,
                    _packageStream,
                    _message,
                    _cancellationToken);

                // Assert
                Validate(result, ValidationStatus.Failed, signingStatus, shouldExtract: signingStatus == PackageSigningStatus.Valid);
                Assert.Empty(result.Issues);
            }
Exemple #5
0
        public async Task RejectsNonAuthorSignature()
        {
            // Arrange
            var content = new SignatureContent(
                SigningSpecifications.V1,
                NuGetHashAlgorithmName.SHA256,
                hashValue: "hash");

            SetSignatureContent(
                TestResources.SignedPackageLeafId,
                TestResources.GetResourceStream(TestResources.SignedPackageLeaf1),
                content.GetBytes());

            // Act
            var result = await _target.ValidateAsync(
                _packageKey,
                _packageStream,
                _message,
                _token);

            // Assert
            VerifyPackageSigningStatus(result, ValidationStatus.Failed, PackageSigningStatus.Invalid);
            var issue = Assert.Single(result.Issues);

            Assert.Equal(ValidationIssueCode.OnlyAuthorSignaturesSupported, issue.IssueCode);
        }
Exemple #6
0
            public async Task WhenRepositorySigningIsRequired_FailsValidationOfSignedPackagesWithNoRepositorySignature()
            {
                // Arrange
                _packageStream = TestResources.GetResourceStream(TestResources.SignedPackageLeaf1);
                TestUtility.RequireSignedPackage(
                    _corePackageService,
                    TestResources.SignedPackageLeafId,
                    TestResources.SignedPackageLeaf1Version,
                    TestResources.Leaf1Thumbprint);
                _message = new SignatureValidationMessage(
                    TestResources.SignedPackageLeafId,
                    TestResources.SignedPackageLeaf1Version,
                    new Uri($"https://unit.test/{TestResources.SignedPackageLeaf1.ToLowerInvariant()}"),
                    Guid.NewGuid(),
                    requireRepositorySignature: true);

                // Act
                var result = await _target.ValidateAsync(
                    _packageKey,
                    _packageStream,
                    _message,
                    _cancellationToken);

                // Assert
                Validate(result, ValidationStatus.Failed, PackageSigningStatus.Valid, shouldExtract: true);
                Assert.Empty(result.Issues);
            }
Exemple #7
0
            public async Task AcceptsSignedPackagesWithUnknownCertificatesOnRevalidation()
            {
                // Arrange
                _packageStream = TestResources.GetResourceStream(TestResources.SignedPackageLeaf1);
                TestUtility.RequireSignedPackage(
                    _corePackageService,
                    TestResources.SignedPackageLeafId,
                    TestResources.SignedPackageLeaf1Version,
                    TestResources.Leaf2Thumbprint,
                    PackageStatus.Available);

                _message = new SignatureValidationMessage(
                    TestResources.SignedPackageLeafId,
                    TestResources.SignedPackageLeaf1Version,
                    new Uri($"https://unit.test/{TestResources.SignedPackageLeaf1.ToLowerInvariant()}"),
                    Guid.NewGuid());

                // Act
                var result = await _target.ValidateAsync(
                    _packageKey,
                    _packageStream,
                    _message,
                    _cancellationToken);

                // Assert
                Validate(result, ValidationStatus.Succeeded, PackageSigningStatus.Valid);
                Assert.Empty(result.Issues);
            }
            public async Task RejectsSignedPackagesWithUnknownCertificates()
            {
                // Arrange
                _packageStream = TestResources.GetResourceStream(TestResources.SignedPackageLeaf1);
                TestUtility.RequireSignedPackage(
                    _corePackageService,
                    TestResources.SignedPackageLeafId,
                    TestResources.Leaf2Thumbprint);
                _message = new SignatureValidationMessage(
                    TestResources.SignedPackageLeafId,
                    TestResources.SignedPackageLeaf1Version,
                    new Uri($"https://unit.test/{TestResources.SignedPackageLeaf1.ToLowerInvariant()}"),
                    Guid.NewGuid());

                // Act
                var result = await _target.ValidateAsync(
                    _packageKey,
                    _packageStream,
                    _message,
                    _cancellationToken);

                // Assert
                Validate(result, ValidationStatus.Failed, PackageSigningStatus.Invalid);
                Assert.Single(result.Issues);
                var issue = Assert.IsType <UnauthorizedCertificateFailure>(result.Issues[0]);

                Assert.Equal(ValidationIssueCode.PackageIsSignedWithUnauthorizedCertificate, issue.IssueCode);
                Assert.Equal(TestResources.Leaf2Sha1Thumbprint, issue.Sha1Thumbprint);
            }
Exemple #9
0
        public async Task RejectsInvalidSignatureContent()
        {
            // Arrange
            SetSignatureContent(
                TestResources.SignedPackageLeafId,
                TestResources.GetResourceStream(TestResources.SignedPackageLeaf1),
                "!!--:::FOO...");

            // Act
            var result = await _target.ValidateAsync(
                _packageKey,
                _packageStream,
                _message,
                _token);

            // Assert
            VerifyPackageSigningStatus(result, ValidationStatus.Failed, PackageSigningStatus.Invalid);
            var issue = Assert.Single(result.Issues);

            Assert.Equal(ValidationIssueCode.ClientSigningVerificationFailure, issue.IssueCode);
            var typedIssue = Assert.IsType <ClientSigningVerificationFailure>(issue);

            Assert.Equal("NU3000", typedIssue.ClientCode);
            Assert.Equal("The package signature content is invalid.", typedIssue.ClientMessage);
        }
            public async Task RejectsSignedPackagesWithFailedMinimalVerifyResult()
            {
                // Arrange
                _packageStream       = TestResources.GetResourceStream(TestResources.SignedPackageLeaf1);
                _mimimalVerifyResult = new VerifySignaturesResult(valid: false);
                _message             = new SignatureValidationMessage(
                    TestResources.SignedPackageLeafId,
                    TestResources.SignedPackageLeaf1Version,
                    new Uri($"https://unit.test/{TestResources.SignedPackageLeaf1.ToLowerInvariant()}"),
                    Guid.NewGuid());

                // Act
                var result = await _target.ValidateAsync(
                    _packageKey,
                    _packageStream,
                    _message,
                    _cancellationToken);

                // Assert
                Validate(result, ValidationStatus.Failed, PackageSigningStatus.Invalid);
                Assert.Empty(result.Issues);
                _fullPackageSignatureVerifier.Verify(
                    x => x.VerifySignaturesAsync(It.IsAny <ISignedPackageReader>(), It.IsAny <CancellationToken>(), It.IsAny <Guid>()),
                    Times.Never);
            }
Exemple #11
0
        public async Task RejectsMultipleSignatures()
        {
            // Arrange
            SetSignatureContent(
                TestResources.SignedPackageLeafId,
                TestResources.GetResourceStream(TestResources.SignedPackageLeaf1),
                configuredSignedCms: signedCms =>
            {
                using (var additionalCertificate = SigningTestUtility.GenerateCertificate(subjectName: null, modifyGenerator: null))
                {
                    TestUtility.RequireSignedPackage(_corePackageService,
                                                     TestResources.SignedPackageLeafId,
                                                     additionalCertificate.ComputeSHA256Thumbprint());
                    signedCms.ComputeSignature(new CmsSigner(additionalCertificate));
                }
            });

            // Act
            var result = await _target.ValidateAsync(
                _packageKey,
                _packageStream,
                _message,
                _token);

            // Assert
            VerifyPackageSigningStatus(result, ValidationStatus.Failed, PackageSigningStatus.Invalid);
            var issue = Assert.Single(result.Issues);

            Assert.Equal(ValidationIssueCode.ClientSigningVerificationFailure, issue.IssueCode);
            var typedIssue = Assert.IsType <ClientSigningVerificationFailure>(issue);

            Assert.Equal("NU3009", typedIssue.ClientCode);
            Assert.Equal("The package signature file does not contain exactly one primary signature.", typedIssue.ClientMessage);
        }
Exemple #12
0
        public async Task RejectsUntrustedSigningCertificate()
        {
            // Arrange
            TestUtility.RequireSignedPackage(_corePackageService, TestResources.SignedPackageLeafId, TestResources.Leaf1Thumbprint);
            _packageStream = TestResources.GetResourceStream(TestResources.SignedPackageLeaf1);

            _message = new SignatureValidationMessage(
                TestResources.SignedPackageLeafId,
                TestResources.SignedPackageLeaf1Version,
                new Uri($"https://unit.test/validation/{TestResources.SignedPackageLeaf1.ToLowerInvariant()}"),
                Guid.NewGuid());

            // Act
            var result = await _target.ValidateAsync(
                _packageKey,
                _packageStream,
                _message,
                _token);

            // Assert
            VerifyPackageSigningStatus(result, ValidationStatus.Failed, PackageSigningStatus.Invalid);
            var issue       = Assert.Single(result.Issues);
            var clientIssue = Assert.IsType <ClientSigningVerificationFailure>(issue);

            Assert.Equal("NU3012", clientIssue.ClientCode);
            Assert.Equal(
                "A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider.",
                clientIssue.ClientMessage);
        }
            public async Task VerifiesTheDownloadedStream()
            {
                // Arrange
                var stream = TestResources.GetResourceStream(TestResources.SignedPackageLeaf1);

                _packageDownloader
                .Setup(x => x.DownloadAsync(_message.NupkgUri, It.IsAny <CancellationToken>()))
                .ReturnsAsync(() => FileDownloadResult.Ok(stream));

                // Act
                var success = await _target.HandleAsync(_message);

                // Assert
                Assert.True(success, "The handler should have succeeded processing the message.");
                _signatureValidator.Verify(
                    x => x.ValidateAsync(
                        _validation.PackageKey,
                        stream,
                        _message,
                        CancellationToken.None),
                    Times.Once);
                _signatureValidator.Verify(
                    x => x.ValidateAsync(
                        It.IsAny <int>(),
                        It.IsAny <Stream>(),
                        It.IsAny <SignatureValidationMessage>(),
                        It.IsAny <CancellationToken>()),
                    Times.Once);
            }
Exemple #14
0
            public ValidateAsync(ITestOutputHelper output)
            {
                _packageStream = TestResources.GetResourceStream(TestResources.UnsignedPackage);
                _packageKey    = 42;
                _message       = new SignatureValidationMessage(
                    "NuGet.Versioning",
                    "4.3.0",
                    new Uri("https://example/nuget.versioning.4.3.0.nupkg"),
                    new Guid("b777135f-1aac-4ec2-a3eb-1f64fe1880d5"));
                _cancellationToken = CancellationToken.None;

                _packageSigningStateService = new Mock <IPackageSigningStateService>();
                _formatValidator            = new Mock <ISignatureFormatValidator>();

                _minimalVerifyResult = new VerifySignaturesResult(valid: true, signed: true);
                _formatValidator
                .Setup(x => x.ValidateMinimalAsync(It.IsAny <ISignedPackageReader>(), It.IsAny <CancellationToken>()))
                .ReturnsAsync(() => _minimalVerifyResult);

                _fullVerifyResult = new VerifySignaturesResult(valid: true, signed: true);
                _formatValidator
                .Setup(x => x.ValidateAllSignaturesAsync(It.IsAny <ISignedPackageReader>(), It.IsAny <bool>(), It.IsAny <CancellationToken>()))
                .ReturnsAsync(() => _fullVerifyResult);

                _signaturePartsExtractor = new Mock <ISignaturePartsExtractor>();
                _corePackageService      = new Mock <ICorePackageService>();
                var loggerFactory = new LoggerFactory().AddXunit(output);

                _logger = loggerFactory.CreateLogger <SignatureValidator>();

                _packageFileService = new Mock <IProcessorPackageFileService>();
                _nupkgUri           = new Uri("https://example-storage/TestProcessor/b777135f-1aac-4ec2-a3eb-1f64fe1880d5/nuget.versioning.4.3.0.nupkg");
                _packageFileService
                .Setup(x => x.GetReadAndDeleteUriAsync(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <Guid>()))
                .ReturnsAsync(() => _nupkgUri);

                _optionsSnapshot = new Mock <IOptionsSnapshot <ProcessSignatureConfiguration> >();
                _configuration   = new ProcessSignatureConfiguration
                {
                    AllowedRepositorySigningCertificates = new List <string> {
                        "fake-thumbprint"
                    },
                    V3ServiceIndexUrl = "http://example/v3/index.json",
                };
                _optionsSnapshot.Setup(x => x.Value).Returns(() => _configuration);

                _telemetryService = new Mock <ITelemetryService>();

                _target = new SignatureValidator(
                    _packageSigningStateService.Object,
                    _formatValidator.Object,
                    _signaturePartsExtractor.Object,
                    _packageFileService.Object,
                    _corePackageService.Object,
                    _optionsSnapshot.Object,
                    _telemetryService.Object,
                    _logger);
            }
Exemple #15
0
            public async Task RejectsPackagesWithFullVerificationErrors()
            {
                // Arrange
                _packageStream = TestResources.GetResourceStream(TestResources.SignedPackageLeaf1);
                TestUtility.RequireSignedPackage(
                    _corePackageService,
                    TestResources.SignedPackageLeafId,
                    TestResources.SignedPackageLeaf1Version,
                    TestResources.Leaf1Thumbprint);
                _fullVerifyResult = new VerifySignaturesResult(
                    valid: false,
                    signed: true,
                    results: new[]
                {
                    new InvalidSignaturePackageVerificationResult(
                        SignatureVerificationStatus.Suspect,
                        new[]
                    {
                        SignatureLog.Issue(
                            fatal: true,
                            code: NuGetLogCode.NU3008,
                            message: "The package integrity check failed."),
                        SignatureLog.Issue(
                            fatal: false,
                            code: NuGetLogCode.NU3016,
                            message: "The package hash uses an unsupported hash algorithm."),
                        SignatureLog.Issue(
                            fatal: true,
                            code: NuGetLogCode.NU3000,
                            message: "Some other thing happened."),
                    })
                });
                _message = new SignatureValidationMessage(
                    TestResources.SignedPackageLeafId,
                    TestResources.SignedPackageLeaf1Version,
                    new Uri($"https://unit.test/{TestResources.SignedPackageLeaf1.ToLowerInvariant()}"),
                    Guid.NewGuid());

                // Act
                var result = await _target.ValidateAsync(
                    _packageKey,
                    _packageStream,
                    _message,
                    _cancellationToken);

                // Assert
                Validate(result, ValidationStatus.Failed, PackageSigningStatus.Invalid);
                Assert.Equal(2, result.Issues.Count);
                var issue1 = Assert.IsType <ClientSigningVerificationFailure>(result.Issues[0]);

                Assert.Equal("NU3008", issue1.ClientCode);
                Assert.Equal("The package integrity check failed.", issue1.ClientMessage);
                var issue2 = Assert.IsType <ClientSigningVerificationFailure>(result.Issues[1]);

                Assert.Equal("NU3000", issue2.ClientCode);
                Assert.Equal("Some other thing happened.", issue2.ClientMessage);
            }
            public async Task WhenPackageSupportsButDoesNotRequireSigning_AcceptsUnsignedPackages()
            {
                // Arrange
                var user1 = new User()
                {
                    Key = 1
                };
                var user2 = new User()
                {
                    Key = 2
                };
                var packageRegistration = new PackageRegistration()
                {
                    Key = 3,
                    Id  = TestResources.UnsignedPackageId
                };
                var certificate = new Certificate()
                {
                    Key        = 4,
                    Thumbprint = TestResources.Leaf1Thumbprint
                };
                var userCertificate = new UserCertificate()
                {
                    Key            = 5,
                    CertificateKey = certificate.Key,
                    Certificate    = certificate,
                    UserKey        = user1.Key,
                    User           = user1
                };

                user1.UserCertificates.Add(userCertificate);
                certificate.UserCertificates.Add(userCertificate);

                packageRegistration.Owners.Add(user1);
                packageRegistration.Owners.Add(user2);

                _packageStream = TestResources.GetResourceStream(TestResources.UnsignedPackage);
                _corePackageService
                .Setup(x => x.FindPackageRegistrationById(It.Is <string>(id => id == _message.PackageId)))
                .Returns(packageRegistration);
                _message = new SignatureValidationMessage(
                    TestResources.UnsignedPackageId,
                    TestResources.UnsignedPackageVersion,
                    new Uri($"https://unit.test/{TestResources.UnsignedPackage.ToLowerInvariant()}"),
                    Guid.NewGuid());

                // Act
                var result = await _target.ValidateAsync(
                    _packageKey,
                    _packageStream,
                    _message,
                    _cancellationToken);

                // Assert
                Validate(result, ValidationStatus.Succeeded, PackageSigningStatus.Unsigned);
                Assert.Empty(result.Issues);
            }
Exemple #17
0
            public async Task WhenStripsValidRepositorySignature_StripsAndAcceptsRepositorySignatureWhenRepositorySignatureIsNotRequired(
                string resourceName,
                string packageId,
                string packageVersion,
                PackageSigningStatus expectedSigningStatus)
            {
                // Arrange
                _configuration.StripValidRepositorySignatures       = true;
                _configuration.AllowedRepositorySigningCertificates = new List <string> {
                    TestResources.Leaf1Thumbprint, TestResources.Leaf2Thumbprint
                };

                _packageStream = TestResources.GetResourceStream(resourceName);

                if (resourceName == TestResources.RepoSignedPackageLeaf1)
                {
                    TestUtility.RequireUnsignedPackage(_corePackageService, TestResources.RepoSignedPackageLeafId, TestResources.RepoSignedPackageLeaf1Version);
                }

                if (resourceName == TestResources.AuthorAndRepoSignedPackageLeaf1)
                {
                    TestUtility.RequireSignedPackage(_corePackageService, TestResources.AuthorAndRepoSignedPackageLeafId, TestResources.AuthorAndRepoSignedPackageLeaf1Version, TestResources.Leaf1Thumbprint);
                }

                _message = new SignatureValidationMessage(
                    packageId,
                    packageVersion,
                    new Uri($"https://unit.test/{resourceName.ToLowerInvariant()}"),
                    Guid.NewGuid(),
                    requireRepositorySignature: false);

                Stream uploadedStream = null;

                _packageFileService
                .Setup(x => x.SaveAsync(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <Guid>(), It.IsAny <Stream>()))
                .Returns(Task.CompletedTask)
                .Callback <string, string, Guid, Stream>((_, __, ___, s) => uploadedStream = s);

                // Act
                var result = await _target.ValidateAsync(
                    _packageKey,
                    _packageStream,
                    _message,
                    _cancellationToken);

                // Assert
                Validate(result, ValidationStatus.Succeeded, expectedSigningStatus, _nupkgUri);
                Assert.Empty(result.Issues);
                _packageFileService.Verify(
                    x => x.SaveAsync(_message.PackageId, _message.PackageVersion, _message.ValidationId, It.IsAny <Stream>()),
                    Times.Once);
                _packageFileService.Verify(
                    x => x.GetReadAndDeleteUriAsync(_message.PackageId, _message.PackageVersion, _message.ValidationId),
                    Times.Once);
                Assert.IsType <FileStream>(uploadedStream);
                Assert.Throws <ObjectDisposedException>(() => uploadedStream.Length);
            }
Exemple #18
0
 public Task <byte[]> GenerateSignedPackageBytesAsync(
     string resourceName,
     X509Certificate2 certificate,
     Uri timestampUri,
     ITestOutputHelper output)
 {
     return(GenerateSignedPackageBytesAsync(
                TestResources.GetResourceStream(resourceName),
                new AuthorSignPackageRequest(certificate, HashAlgorithmName.SHA256),
                timestampUri,
                output));
 }
            public HandleAsync()
            {
                _message = new SignatureValidationMessage(
                    "NuGet.Versioning",
                    "4.3.0",
                    TestPackageUri,
                    new Guid("18e83aca-953a-4484-a698-a8fb8619e0bd"));
                _outputNupkgUri = new Uri("https://example/processor/18e83aca-953a-4484-a698-a8fb8619e0bd/nuget.versioning.4.3.0.nupkg");

                _validation = new ValidatorStatus
                {
                    PackageKey = 42,
                    State      = ValidationStatus.Incomplete,
                };
                _validationIssue = new Mock <IValidationIssue>();
                _validatorResult = new SignatureValidatorResult(ValidationStatus.Succeeded, nupkgUri: null);

                _packageDownloader     = new Mock <IFileDownloader>();
                _validatorStateService = new Mock <IValidatorStateService>();
                _signatureValidator    = new Mock <ISignatureValidator>();
                _validationEnqueuer    = new Mock <IPackageValidationEnqueuer>();
                _featureFlagService    = new Mock <IFeatureFlagService>();
                _logger = new Mock <ILogger <SignatureValidationMessageHandler> >();

                _packageDownloader
                .Setup(x => x.DownloadAsync(_message.NupkgUri, It.IsAny <CancellationToken>()))
                .ReturnsAsync(() => FileDownloadResult.Ok(TestResources.GetResourceStream(TestResources.UnsignedPackage)));
                _validatorStateService
                .Setup(x => x.GetStatusAsync(It.IsAny <Guid>()))
                .ReturnsAsync(() => _validation);

                _signatureValidator
                .Setup(x => x.ValidateAsync(
                           It.IsAny <int>(),
                           It.IsAny <Stream>(),
                           It.IsAny <SignatureValidationMessage>(),
                           It.IsAny <CancellationToken>()))
                .ReturnsAsync(() => _validatorResult);

                _featureFlagService.SetReturnsDefault(true);

                _target = new SignatureValidationMessageHandler(
                    _packageDownloader.Object,
                    _validatorStateService.Object,
                    _signatureValidator.Object,
                    _validationEnqueuer.Object,
                    _featureFlagService.Object,
                    _logger.Object);
            }
            public ValidateAsync(ITestOutputHelper output)
            {
                _packageStream = TestResources.GetResourceStream(TestResources.UnsignedPackage);
                _packageKey    = 42;
                _message       = new SignatureValidationMessage(
                    "NuGet.Versioning",
                    "4.3.0",
                    new Uri("https://example/nuget.versioning.4.3.0.nupkg"),
                    new Guid("b777135f-1aac-4ec2-a3eb-1f64fe1880d5"));
                _cancellationToken = CancellationToken.None;

                _packageSigningStateService = new Mock <IPackageSigningStateService>();

                _mimimalVerifyResult             = new VerifySignaturesResult(true);
                _mimimalPackageSignatureVerifier = new Mock <IPackageSignatureVerifier>();
                _mimimalPackageSignatureVerifier
                .Setup(x => x.VerifySignaturesAsync(It.IsAny <ISignedPackageReader>(), It.IsAny <CancellationToken>(), It.IsAny <Guid>()))
                .ReturnsAsync(() => _mimimalVerifyResult);

                _fullVerifyResult             = new VerifySignaturesResult(true);
                _fullPackageSignatureVerifier = new Mock <IPackageSignatureVerifier>();
                _fullPackageSignatureVerifier
                .Setup(x => x.VerifySignaturesAsync(It.IsAny <ISignedPackageReader>(), It.IsAny <CancellationToken>(), It.IsAny <Guid>()))
                .ReturnsAsync(() => _fullVerifyResult);

                _signaturePartsExtractor = new Mock <ISignaturePartsExtractor>();
                _corePackageService      = new Mock <ICorePackageService>();
                var loggerFactory = new LoggerFactory().AddXunit(output);

                _logger = loggerFactory.CreateLogger <SignatureValidator>();

                _packageFileService = new Mock <IProcessorPackageFileService>();
                _nupkgUri           = new Uri("https://example-storage/TestProcessor/b777135f-1aac-4ec2-a3eb-1f64fe1880d5/nuget.versioning.4.3.0.nupkg");
                _packageFileService
                .Setup(x => x.GetReadAndDeleteUriAsync(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <Guid>()))
                .ReturnsAsync(() => _nupkgUri);

                _telemetryService = new Mock <ITelemetryService>();

                _target = new SignatureValidator(
                    _packageSigningStateService.Object,
                    _mimimalPackageSignatureVerifier.Object,
                    _fullPackageSignatureVerifier.Object,
                    _signaturePartsExtractor.Object,
                    _packageFileService.Object,
                    _corePackageService.Object,
                    _telemetryService.Object,
                    _logger);
            }
            public async Task StripsAndAcceptsPackagesWithRepositorySignatures(
                string resourceName,
                string packageId,
                string packageVersion,
                PackageSigningStatus signingStatus,
                bool allowSignedPackage)
            {
                // Arrange
                _packageStream = TestResources.GetResourceStream(resourceName);
                if (allowSignedPackage)
                {
                    TestUtility.RequireSignedPackage(_corePackageService, packageId, TestResources.Leaf1Thumbprint);
                }
                else
                {
                    TestUtility.RequireUnsignedPackage(_corePackageService, packageId);
                }
                _message = new SignatureValidationMessage(
                    packageId,
                    packageVersion,
                    new Uri($"https://unit.test/{resourceName.ToLowerInvariant()}"),
                    Guid.NewGuid());

                Stream uploadedStream = null;

                _packageFileService
                .Setup(x => x.SaveAsync(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <Guid>(), It.IsAny <Stream>()))
                .Returns(Task.CompletedTask)
                .Callback <string, string, Guid, Stream>((_, __, ___, s) => uploadedStream = s);

                // Act
                var result = await _target.ValidateAsync(
                    _packageKey,
                    _packageStream,
                    _message,
                    _cancellationToken);

                // Assert
                Validate(result, ValidationStatus.Succeeded, signingStatus, _nupkgUri);
                Assert.Empty(result.Issues);
                _packageFileService.Verify(
                    x => x.SaveAsync(_message.PackageId, _message.PackageVersion, _message.ValidationId, It.IsAny <Stream>()),
                    Times.Once);
                _packageFileService.Verify(
                    x => x.GetReadAndDeleteUriAsync(_message.PackageId, _message.PackageVersion, _message.ValidationId),
                    Times.Once);
                Assert.IsType <FileStream>(uploadedStream);
                Assert.Throws <ObjectDisposedException>(() => uploadedStream.Length);
            }
            public async Task RejectsZip64Packages()
            {
                // Arrange
                _packageStream = TestResources.GetResourceStream(TestResources.Zip64Package);

                // Act
                var result = await _target.ValidateAsync(
                    _packageKey,
                    _packageStream,
                    _message,
                    _cancellationToken);

                // Assert
                Validate(result, ValidationStatus.Failed, PackageSigningStatus.Invalid);
                var issue = Assert.Single(result.Issues);

                Assert.Equal(ValidationIssueCode.PackageIsZip64, issue.IssueCode);
            }
Exemple #23
0
        public async Task StripsRepositorySignatures()
        {
            // Arrange
            _message = new SignatureValidationMessage(
                TestResources.UnsignedPackageId,
                TestResources.UnsignedPackageVersion,
                new Uri($"https://unit.test/validation/{TestResources.UnsignedPackage.ToLowerInvariant()}"),
                Guid.NewGuid());
            var packageBytes = await _fixture.GenerateSignedPackageBytesAsync(
                TestResources.GetResourceStream(TestResources.UnsignedPackage),
                new RepositorySignPackageRequest(
                    await _fixture.GetSigningCertificateAsync(),
                    NuGetHashAlgorithmName.SHA256,
                    NuGetHashAlgorithmName.SHA256,
                    new Uri("https://example-source/v3/index.json"),
                    new[] { "nuget", "microsoft" }),
                await _fixture.GetTimestampServiceUrlAsync(),
                _output);

            var packageStream = new MemoryStream(packageBytes);

            TestUtility.RequireUnsignedPackage(_corePackageService, TestResources.UnsignedPackageId);

            // Act
            var result = await _target.ValidateAsync(
                _packageKey,
                packageStream,
                _message,
                _token);

            // Assert
            VerifyPackageSigningStatus(result, ValidationStatus.Succeeded, PackageSigningStatus.Unsigned);
            Assert.Empty(result.Issues);
            Assert.Equal(_nupkgUri, result.NupkgUri);
            Assert.NotNull(_savedPackageBytes);
            using (var savedPackageStream = new MemoryStream(_savedPackageBytes))
                using (var packageReader = new SignedPackageArchive(savedPackageStream, Stream.Null))
                {
                    Assert.Equal("TestUnsigned", packageReader.NuspecReader.GetId());
                    Assert.Equal("1.0.0", packageReader.NuspecReader.GetVersion().ToNormalizedString());
                    Assert.False(await packageReader.IsSignedAsync(CancellationToken.None), "The package should no longer be signed.");
                }
        }
            public async Task DoesNotUploadPackageWhenValidationFailed()
            {
                // Arrange
                _packageStream = TestResources.GetResourceStream(TestResources.AuthorAndRepoSignedPackageLeaf1);
                TestUtility.RequireUnsignedPackage(_corePackageService, _message.PackageId);

                // Act
                var result = await _target.ValidateAsync(
                    _packageKey,
                    _packageStream,
                    _message,
                    _cancellationToken);

                // Assert
                Validate(result, ValidationStatus.Failed, PackageSigningStatus.Invalid);
                _packageFileService.Verify(
                    x => x.SaveAsync(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <Guid>(), It.IsAny <Stream>()),
                    Times.Never);
            }
Exemple #25
0
            public async Task WhenStripsValidRepositorySignature_AcceptsRepositorySignatureWhenRepositorySignatureIsRequired(
                string resourceName,
                string packageId,
                string packageVersion,
                PackageSigningStatus expectedSigningStatus)
            {
                // Arrange
                _configuration.StripValidRepositorySignatures       = true;
                _configuration.AllowedRepositorySigningCertificates = new List <string> {
                    TestResources.Leaf1Thumbprint, TestResources.Leaf2Thumbprint
                };

                _packageStream = TestResources.GetResourceStream(resourceName);

                if (resourceName == TestResources.RepoSignedPackageLeaf1)
                {
                    TestUtility.RequireUnsignedPackage(_corePackageService, TestResources.RepoSignedPackageLeafId, TestResources.RepoSignedPackageLeaf1Version);
                }

                if (resourceName == TestResources.AuthorAndRepoSignedPackageLeaf1)
                {
                    TestUtility.RequireSignedPackage(_corePackageService, TestResources.AuthorAndRepoSignedPackageLeafId, TestResources.AuthorAndRepoSignedPackageLeaf1Version, TestResources.Leaf1Thumbprint);
                }

                _message = new SignatureValidationMessage(
                    packageId,
                    packageVersion,
                    new Uri($"https://unit.test/{resourceName.ToLowerInvariant()}"),
                    Guid.NewGuid(),
                    requireRepositorySignature: true);

                // Act
                var result = await _target.ValidateAsync(
                    _packageKey,
                    _packageStream,
                    _message,
                    _cancellationToken);

                // Assert
                Validate(result, ValidationStatus.Succeeded, expectedSigningStatus);
                Assert.Empty(result.Issues);
            }
Exemple #26
0
        public async Task RejectInvalidSignatureContentVersion()
        {
            // Arrange
            SetSignatureContent(
                TestResources.SignedPackageLeafId,
                TestResources.GetResourceStream(TestResources.SignedPackageLeaf1),
                "Version:2" + Environment.NewLine + Environment.NewLine + "2.16.840.1.101.3.4.2.1-Hash:hash");

            // Act
            var result = await _target.ValidateAsync(
                _packageKey,
                _packageStream,
                _message,
                _token);

            // Assert
            VerifyPackageSigningStatus(result, ValidationStatus.Failed, PackageSigningStatus.Invalid);
            var issue = Assert.Single(result.Issues);

            Assert.Equal(ValidationIssueCode.OnlySignatureFormatVersion1Supported, issue.IssueCode);
        }
Exemple #27
0
            public async Task RejectsPackagesWithMimimalVerificationErrors()
            {
                // Arrange
                _packageStream       = TestResources.GetResourceStream(TestResources.SignedPackageLeaf1);
                _minimalVerifyResult = new VerifySignaturesResult(
                    valid: false,
                    signed: true,
                    results: new[]
                {
                    new InvalidSignaturePackageVerificationResult(
                        SignatureVerificationStatus.Suspect,
                        new[]
                    {
                        SignatureLog.Issue(
                            fatal: true,
                            code: NuGetLogCode.NU3000,
                            message: "The package signature is invalid."),
                    })
                });
                _message = new SignatureValidationMessage(
                    TestResources.SignedPackageLeafId,
                    TestResources.SignedPackageLeaf1Version,
                    new Uri($"https://unit.test/{TestResources.SignedPackageLeaf1.ToLowerInvariant()}"),
                    Guid.NewGuid());

                // Act
                var result = await _target.ValidateAsync(
                    _packageKey,
                    _packageStream,
                    _message,
                    _cancellationToken);

                // Assert
                Validate(result, ValidationStatus.Failed, PackageSigningStatus.Invalid);
                Assert.Single(result.Issues);
                var issue = Assert.IsType <ClientSigningVerificationFailure>(result.Issues[0]);

                Assert.Equal("NU3000", issue.ClientCode);
                Assert.Equal("The package signature is invalid.", issue.ClientMessage);
            }
        private HttpResponseMessage Send(HttpRequestMessage request)
        {
            if (request.Method != HttpMethod.Get ||
                !_urlToResourceName.TryGetValue(request.RequestUri, out var resourceName))
            {
                return(new HttpResponseMessage(HttpStatusCode.NotFound));
            }

            var resourceStream = TestResources.GetResourceStream(resourceName);

            if (resourceStream == null)
            {
                return(new HttpResponseMessage(HttpStatusCode.NotFound));
            }

            return(new HttpResponseMessage
            {
                StatusCode = HttpStatusCode.OK,
                RequestMessage = request,
                Content = new StreamContent(resourceStream),
            });
        }
            public async Task WhenPackageRequiresUnsignedPackages_AcceptsUnsignedPackages()
            {
                // Arrange
                _packageStream = TestResources.GetResourceStream(TestResources.UnsignedPackage);
                TestUtility.RequireUnsignedPackage(_corePackageService, TestResources.UnsignedPackageId);
                _message = new SignatureValidationMessage(
                    TestResources.UnsignedPackageId,
                    TestResources.UnsignedPackageVersion,
                    new Uri($"https://unit.test/{TestResources.UnsignedPackage.ToLowerInvariant()}"),
                    Guid.NewGuid());

                // Act
                var result = await _target.ValidateAsync(
                    _packageKey,
                    _packageStream,
                    _message,
                    _cancellationToken);

                // Assert
                Validate(result, ValidationStatus.Succeeded, PackageSigningStatus.Unsigned);
                Assert.Empty(result.Issues);
            }
            public async Task RejectsUnsignedPackagesWhenSigningIsRequired()
            {
                // Arrange
                _packageStream = TestResources.GetResourceStream(TestResources.UnsignedPackage);
                TestUtility.RequireSignedPackage(_corePackageService, TestResources.UnsignedPackageId);
                _message = new SignatureValidationMessage(
                    TestResources.UnsignedPackageId,
                    TestResources.UnsignedPackageVersion,
                    new Uri($"https://unit.test/{TestResources.UnsignedPackage.ToLowerInvariant()}"),
                    Guid.NewGuid());

                // Act
                var result = await _target.ValidateAsync(
                    _packageKey,
                    _packageStream,
                    _message,
                    _cancellationToken);

                // Assert
                Validate(result, ValidationStatus.Failed, PackageSigningStatus.Invalid);
                var issue = Assert.Single(result.Issues);

                Assert.Equal(ValidationIssueCode.PackageIsNotSigned, issue.IssueCode);
            }