public async Task GetTimestamp_WhenSignatureHashAlgorithmIsSha1_Throws() { var testServer = await _testFixture.GetSigningTestServerAsync(); var certificateAuthority = await _testFixture.GetDefaultTrustedCertificateAuthorityAsync(); var options = new TimestampServiceOptions() { SignatureHashAlgorithm = new Oid(Oids.Sha1) }; var timestampService = TimestampService.Create(certificateAuthority, options); VerifyTimestampData( testServer, timestampService, (timestampProvider, request) => { var exception = Assert.Throws <TimestampException>( () => timestampProvider.GetTimestamp(request, NullLogger.Instance, CancellationToken.None)); Assert.Equal( "The timestamp certificate has an unsupported signature algorithm.", exception.Message); }); }
public async Task GetTimestamp_WithFailureReponse_Throws() { var testServer = await _testFixture.GetSigningTestServerAsync(); var certificateAuthority = await _testFixture.GetDefaultTrustedCertificateAuthorityAsync(); var options = new TimestampServiceOptions() { ReturnFailure = true }; var timestampService = TimestampService.Create(certificateAuthority, options); VerifyTimestampData( testServer, timestampService, (timestampProvider, request) => { var exception = Assert.Throws <CryptographicException>( () => timestampProvider.GetTimestamp(request, NullLogger.Instance, CancellationToken.None)); Assert.StartsWith( "The timestamp signature and/or certificate could not be verified or is malformed.", exception.Message); }); }
public async Task GetTimestampAsync_WhenCertificateSignatureAlgorithmIsSha1_ThrowsAsync() { var testServer = await _testFixture.GetSigningTestServerAsync(); var certificateAuthority = await _testFixture.GetDefaultTrustedCertificateAuthorityAsync(); var timestampServiceOptions = new TimestampServiceOptions() { SignatureHashAlgorithm = new Oid(Oids.Sha1) }; var issueCertificateOptions = IssueCertificateOptions.CreateDefaultForTimestampService(); issueCertificateOptions.SignatureAlgorithmName = "SHA1WITHRSA"; var timestampService = TimestampService.Create(certificateAuthority, timestampServiceOptions, issueCertificateOptions); VerifyTimestampData( testServer, timestampService, async(timestampProvider, request) => { var exception = await Assert.ThrowsAsync <TimestampException>( () => timestampProvider.GetTimestampAsync(request, NullLogger.Instance, CancellationToken.None)); Assert.Equal( "The timestamp certificate has an unsupported signature algorithm (SHA1RSA). The following algorithms are supported: SHA256RSA, SHA384RSA, SHA512RSA.", exception.Message); }); }
public async Task GetTimestampAsync_TimestampGeneralizedTimeOutsideCertificateValidityPeriod_FailAsync() { // Arrange var testServer = await _testFixture.GetSigningTestServerAsync(); var certificateAuthority = await _testFixture.GetDefaultTrustedCertificateAuthorityAsync(); var options = new TimestampServiceOptions() { IssuedCertificateNotBefore = DateTimeOffset.UtcNow.AddHours(-1), IssuedCertificateNotAfter = DateTimeOffset.UtcNow.AddHours(1), GeneralizedTime = DateTimeOffset.UtcNow.AddHours(3) }; var timestampService = TimestampService.Create(certificateAuthority, options); VerifyTimestampData( testServer, timestampService, async(timestampProvider, request) => { var exception = await Assert.ThrowsAsync <TimestampException>( () => timestampProvider.GetTimestampAsync(request, NullLogger.Instance, CancellationToken.None)); Assert.Equal(NuGetLogCode.NU3036, exception.Code); Assert.Contains( "The timestamp's generalized time is outside the timestamping certificate's validity period.", exception.Message); }); }
public async Task GetTimestampCertificateChain_WithNoSigningCertificateUsage_Throws() { ISigningTestServer testServer = await _testFixture.GetSigningTestServerAsync(); CertificateAuthority rootCa = await _testFixture.GetDefaultTrustedCertificateAuthorityAsync(); var options = new TimestampServiceOptions() { SigningCertificateUsage = SigningCertificateUsage.None }; TimestampService timestampService = TimestampService.Create(rootCa, options); using (testServer.RegisterResponder(timestampService)) { var nupkg = new SimpleTestPackageContext(); using (var certificate = new X509Certificate2(_testFixture.TrustedTestCertificate.Source.Cert)) using (TestDirectory directory = TestDirectory.Create()) { string signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync( certificate, nupkg, directory, timestampService.Url); // Act CommandRunnerResult result = RunVerifyCommand(signedPackagePath); // Assert result.Success.Should().BeFalse(because: result.AllOutput); result.AllOutput.Should().Contain("Either the signing-certificate or signing-certificate-v2 attribute must be present."); result.AllOutput.Should().NotContain(_successfullyVerified); } } }
public async Task SignCommand_SignPackageWithUnsuportedTimestampHashAlgorithm_ShouldNotModifyPackageAsync() { var testServer = await _testFixture.GetSigningTestServerAsync(); var certificateAuthority = await _testFixture.GetDefaultTrustedCertificateAuthorityAsync(); var options = new TimestampServiceOptions() { SignatureHashAlgorithm = new Oid(Oids.Sha1) }; var timestampService = TimestampService.Create(certificateAuthority, options); using (testServer.RegisterResponder(timestampService)) using (var directory = TestDirectory.Create()) { var packageContext = new SimpleTestPackageContext(); var packageFile = packageContext.CreateAsFile(directory, fileName: Guid.NewGuid().ToString()); var originalFile = File.ReadAllBytes(packageFile.FullName); using (var certificate = _testFixture.UntrustedSelfIssuedCertificateInCertificateStore) { var result = CommandRunner.Run( _nugetExePath, directory, $"sign {packageFile.FullName} -CertificateFingerprint {certificate.Thumbprint} -Timestamper {timestampService.Url}", waitForExit: true); Assert.False(result.Success); Assert.Contains("The timestamp certificate has an unsupported signature algorithm.", result.AllOutput); var resultingFile = File.ReadAllBytes(packageFile.FullName); Assert.Equal(resultingFile, originalFile); } } }
public async Task VerifySignaturesAsync_ExpiredCertificateAndTimestampWithTooLargeRange_FailsAsync() { ISigningTestServer testServer = await _testFixture.GetSigningTestServerAsync(); CertificateAuthority ca = await _testFixture.GetDefaultTrustedCertificateAuthorityAsync(); var accuracy = new BcAccuracy(seconds: new DerInteger(30), millis: null, micros: null); var serviceOptions = new TimestampServiceOptions() { Accuracy = accuracy }; TimestampService timestampService = TimestampService.Create(ca, serviceOptions); 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 (testServer.RegisterResponder(timestampService)) 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 results = await verifier.VerifySignaturesAsync(packageReader, _verifyCommandSettings, CancellationToken.None); PackageVerificationResult result = results.Results.Single(); Assert.False(results.IsValid); Assert.Equal(SignatureVerificationStatus.Disallowed, result.Trust); Assert.Equal(1, result.Issues.Count(issue => issue.Level == LogLevel.Error)); Assert.Equal(0, result.Issues.Count(issue => issue.Level == LogLevel.Warning)); Assert.Contains(result.Issues, issue => issue.Code == NuGetLogCode.NU3037 && issue.Level == LogLevel.Error && issue.Message.Contains("validity period has expired.")); } } }
public async Task <CustomTimestampService> CreateCustomTimestampServiceAsync(TimestampServiceOptions options) { var testServer = await _testServer.Value; var rootCa = await _rootCertificateAuthority.Value; var timestampService = TimestampService.Create(rootCa, options); var responders = testServer.RegisterDefaultResponders(timestampService); return(new CustomTimestampService( timestampService.Url, responders)); }
public async Task GetTimestampCertificateChain_WithMismatchedEssCertIdCertificateHash_ReturnsChain( SigningCertificateUsage signingCertificateUsage) { ISigningTestServer testServer = await _fixture.GetSigningTestServerAsync(); CertificateAuthority rootCa = await _fixture.GetDefaultTrustedCertificateAuthorityAsync(); var options = new TimestampServiceOptions() { SigningCertificateUsage = signingCertificateUsage, SigningCertificateV1Hash = new byte[SHA1HashLength] }; 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."); } } } } } }
public async Task DotnetSign_SignPackageWithUnsuportedTimestampHashAlgorithm_FailsAsync() { // Arrange using (SimpleTestPathContext pathContext = _msbuildFixture.CreateSimpleTestPathContext()) { await SimpleTestPackageUtility.CreatePackagesAsync( pathContext.PackageSource, new SimpleTestPackageContext("PackageA", "1.0.0")); string packageFilePath = Path.Combine(pathContext.PackageSource, "PackageA.1.0.0.nupkg"); byte[] originalFile = File.ReadAllBytes(packageFilePath); ISigningTestServer testServer = await _signFixture.GetSigningTestServerAsync(); CertificateAuthority certificateAuthority = await _signFixture.GetDefaultTrustedCertificateAuthorityAsync(); var options = new TimestampServiceOptions() { SignatureHashAlgorithm = new Oid(Oids.Sha1) }; TimestampService timestampService = TimestampService.Create(certificateAuthority, options); IX509StoreCertificate storeCertificate = _signFixture.UntrustedSelfIssuedCertificateInCertificateStore; using (testServer.RegisterResponder(timestampService)) { // Act CommandRunnerResult result = _msbuildFixture.RunDotnet( pathContext.PackageSource, $"nuget sign {packageFilePath} " + $"--certificate-fingerprint {storeCertificate.Certificate.Thumbprint} " + $"--timestamper {timestampService.Url}", ignoreExitCode: true); // Assert result.Success.Should().BeFalse(because: result.AllOutput); result.AllOutput.Should().Contain(_timestampUnsupportedDigestAlgorithmCode); Assert.Contains("The timestamp signature has an unsupported digest algorithm (SHA1). The following algorithms are supported: SHA256, SHA384, SHA512.", result.AllOutput); byte[] resultingFile = File.ReadAllBytes(packageFilePath); Assert.Equal(resultingFile, originalFile); } } }
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); } } } }
public async Task GetTimestamp_WhenSigningCertificateNotReturned_Throws() { var testServer = await _testFixture.GetSigningTestServerAsync(); var certificateAuthority = await _testFixture.GetDefaultTrustedCertificateAuthorityAsync(); var options = new TimestampServiceOptions() { ReturnSigningCertificate = false }; var timestampService = TimestampService.Create(certificateAuthority, options); VerifyTimestampData( testServer, timestampService, (timestampProvider, request) => { var exception = Assert.Throws <CryptographicException>( () => timestampProvider.GetTimestamp(request, NullLogger.Instance, CancellationToken.None)); Assert.StartsWith("Cannot find object or property.", exception.Message); }); }
public async Task GetTimestampCertificateChain_WithMismatchedEssCertIdCertificateHash_ReturnsChain( SigningCertificateUsage signingCertificateUsage) { ISigningTestServer testServer = await _testFixture.GetSigningTestServerAsync(); CertificateAuthority rootCa = await _testFixture.GetDefaultTrustedCertificateAuthorityAsync(); var options = new TimestampServiceOptions() { SigningCertificateUsage = signingCertificateUsage, SigningCertificateV1Hash = new byte[SHA1HashLength] }; TimestampService timestampService = TimestampService.Create(rootCa, options); using (testServer.RegisterResponder(timestampService)) { var nupkg = new SimpleTestPackageContext(); using (var certificate = new X509Certificate2(_testFixture.TrustedTestCertificate.Source.Cert)) using (TestDirectory directory = TestDirectory.Create()) { string signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync( certificate, nupkg, directory, timestampService.Url); // Act CommandRunnerResult result = RunVerifyCommand(signedPackagePath); // Assert result.Success.Should().BeTrue(because: result.AllOutput); result.AllOutput.Should().Contain(_successfullyVerified); Regex.Matches(result.AllOutput, _noTimestamperWarning).Count.Should().Be(0); } } }
public async Task VerifySignaturesAsync_ExpiredCertificateAndTimestampWithTooLargeRange_Fails() { var testServer = await _testFixture.GetSigningTestServerAsync(); var ca = await _testFixture.GetDefaultTrustedCertificateAuthorityAsync(); var accuracy = new BcAccuracy(seconds: new DerInteger(30), millis: null, micros: null); var serviceOptions = new TimestampServiceOptions() { Accuracy = accuracy }; var timestampService = TimestampService.Create(ca, serviceOptions); 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 (testServer.RegisterResponder(timestampService)) using (var certificate = new X509Certificate2(bcCertificate.GetEncoded())) using (var directory = TestDirectory.Create()) { certificate.PrivateKey = DotNetUtilities.ToRSA(keyPair.Private as RsaPrivateCrtKeyParameters); var packageContext = new SimpleTestPackageContext(); var signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync( certificate, packageContext, directory, timestampService.Url); var waitDuration = (issueOptions.NotAfter - DateTimeOffset.UtcNow).Add(TimeSpan.FromSeconds(1)); // Wait for the certificate to expire. Trust of the signature will require a valid timestamp. if (waitDuration > TimeSpan.Zero) { await Task.Delay(waitDuration); } Assert.True(DateTime.UtcNow > issueOptions.NotAfter); var verifier = new PackageSignatureVerifier(_trustProviders); using (var packageReader = new PackageArchiveReader(signedPackagePath)) { var results = await verifier.VerifySignaturesAsync(packageReader, _verifyCommandSettings, CancellationToken.None); var result = results.Results.Single(); Assert.False(results.Valid); Assert.Equal(SignatureVerificationStatus.Illegal, result.Trust); Assert.Equal(1, result.Issues.Count(issue => issue.Level == LogLevel.Error)); Assert.Equal(0, result.Issues.Count(issue => issue.Level == LogLevel.Warning)); Assert.Contains(result.Issues, issue => issue.Code == NuGetLogCode.NU3011 && issue.Level == LogLevel.Error && issue.Message.Contains("validity period has expired.")); } } }