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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }