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);
            });
        }
Exemplo n.º 3
0
        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);
            });
        }
Exemplo n.º 4
0
        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);
                    }
            }
        }
Exemplo n.º 6
0
        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."));
                            }
                        }
            }
Exemplo n.º 8
0
        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.");
                                    }
                                }
                            }
                    }
            }
        }
Exemplo n.º 10
0
        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);
                    }
            }
        }
Exemplo n.º 14
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."));
                        }
                    }
        }