コード例 #1
0
        /// <summary>
        /// Create a new certificate authority.
        /// </summary>
        ///  <param name="subject">The complete subject list</param>
        /// <param name="certificatePassPhrase">The certificate request password</param>
        /// <param name="privateKeyPath">The full path and file name where the root certificate authority private key is to be place.</param>
        /// <param name="certificatePath">The full path and file name where the root certificate authority should be place.</param>
        /// <param name="days">The number of days the root certificate is to be active.</param>
        public void CreateCertificateAuthority(Subject subject, string certificatePassPhrase, string privateKeyPath, string certificatePath, int days = 7300)
        {
            if (subject == null)
            {
                throw new ArgumentNullException("subject");
            }
            if (String.IsNullOrEmpty(privateKeyPath))
            {
                throw new ArgumentNullException("privateKeyPath");
            }
            if (String.IsNullOrEmpty(certificatePath))
            {
                throw new ArgumentNullException("certificatePath");
            }
            if (days < 1)
            {
                throw new IndexOutOfRangeException("Parameter 'days' must be greater than zero.");
            }

            // Create a new certificate request.
            CertificateAuthority certificate = new CertificateAuthority(
                Nequeo.Security.OpenSsl.Properties.Settings.Default.OpenSSLExecutable,
                Nequeo.Security.OpenSsl.Properties.Settings.Default.OpenSSLConfiguration);

            // Create the certificate.
            certificate.Create(subject, certificatePassPhrase, privateKeyPath, certificatePath, days);
        }
コード例 #2
0
        public async Task <TimestampServiceWithUnavailableRevocation> CreateTimestampServiceWithUnavailableRevocationAsync()
        {
            var testServer      = await _testServer.Value;
            var rootCa          = CertificateAuthority.Create(testServer.Url);
            var rootCertificate = rootCa.Certificate.ToX509Certificate2();

            var trust = new TrustedTestCert <X509Certificate2>(
                rootCertificate,
                certificate => certificate,
                StoreName.Root,
                StoreLocation.LocalMachine);

            var timestampService = TimestampService.Create(rootCa);
            var disposable       = new DisposableList <IDisposable> {
                rootCertificate, trust
            };

            Task WaitForResponseExpirationAsync()
            {
                return(rootCa.OcspResponder.WaitForResponseExpirationAsync(timestampService.Certificate));
            }

            return(new TimestampServiceWithUnavailableRevocation(
                       testServer,
                       timestampService,
                       WaitForResponseExpirationAsync,
                       disposable));
        }
コード例 #3
0
        private async Task <CertificateAuthority> CreateDefaultTrustedCertificateAuthorityAsync()
        {
            var           testServer      = await _testServer.Value;
            var           rootCa          = CertificateAuthority.Create(testServer.Url);
            var           intermediateCa  = rootCa.CreateIntermediateCertificateAuthority();
            var           rootCertificate = new X509Certificate2(rootCa.Certificate.GetEncoded());
            StoreLocation storeLocation   = CertificateStoreUtilities.GetTrustedCertificateStoreLocation();

            _trustedTimestampRoot = TrustedTestCert.Create(
                rootCertificate,
                StoreName.Root,
                storeLocation);

            var ca = intermediateCa;

            while (ca != null)
            {
                _responders.Add(testServer.RegisterResponder(ca));
                _responders.Add(testServer.RegisterResponder(ca.OcspResponder));

                ca = ca.Parent;
            }

            return(intermediateCa);
        }
コード例 #4
0
        public async Task <X509Certificate2> CreateUntrustedRootSigningCertificateAsync()
        {
            var options = IssueCertificateOptions.CreateDefaultForRootCertificateAuthority();

            options.CustomizeCertificate = (X509V3CertificateGenerator generator) =>
            {
                generator.AddExtension(
                    X509Extensions.SubjectKeyIdentifier,
                    critical: false,
                    extensionValue: new SubjectKeyIdentifierStructure(options.KeyPair.Public));
                generator.AddExtension(
                    X509Extensions.BasicConstraints,
                    critical: true,
                    extensionValue: new BasicConstraints(cA: true));
                generator.AddExtension(
                    X509Extensions.KeyUsage,
                    critical: true,
                    extensionValue: new KeyUsage(KeyUsage.DigitalSignature | KeyUsage.KeyCertSign | KeyUsage.CrlSign));
                generator.AddSigningEku();
            };

            var testServer = await GetTestServerAsync();

            var rootCa = CertificateAuthority.Create(testServer.Url, options);

            var certificate = rootCa.Certificate.ToX509Certificate2();

            certificate.PrivateKey = DotNetUtilities.ToRSA(options.KeyPair.Private as RsaPrivateCrtKeyParameters);

            return(certificate);
        }
コード例 #5
0
        public async Task AcceptsTrustedSigningCertificateWithUnavailableRevocation()
        {
            // Arrange
            var testServer = await _fixture.GetTestServerAsync();

            var rootCa             = CertificateAuthority.Create(testServer.Url);
            var intermediateCa     = rootCa.CreateIntermediateCertificateAuthority();
            var rootCertificate    = new X509Certificate2(rootCa.Certificate.GetEncoded());
            var signingCertificate = _fixture.CreateSigningCertificate(intermediateCa);

            using (var trust = new TrustedTestCert <X509Certificate2>(
                       rootCertificate,
                       x => x,
                       StoreName.Root,
                       StoreLocation.LocalMachine))
            {
                byte[] packageBytes;
                using (testServer.RegisterResponders(intermediateCa))
                {
                    packageBytes = await _fixture.GenerateSignedPackageBytesAsync(
                        TestResources.SignedPackageLeaf1,
                        signingCertificate,
                        await _fixture.GetTimestampServiceUrlAsync(),
                        _output);
                }

                // Wait one second for the OCSP response cached by the operating system during signing to get stale.
                // This can be mitigated by leaving the OCSP unavailable during signing once this work item is done:
                // https://github.com/NuGet/Home/issues/6508
                await Task.Delay(TimeSpan.FromSeconds(1));

                TestUtility.RequireSignedPackage(_corePackageService, TestResources.SignedPackageLeafId, signingCertificate.ComputeSHA256Thumbprint());

                _packageStream = new MemoryStream(packageBytes);

                SignatureValidatorResult result;
                using (testServer.RegisterResponders(intermediateCa, addOcsp: false))
                {
                    // Act
                    result = await _target.ValidateAsync(
                        _packageKey,
                        _packageStream,
                        _message,
                        _token);
                }

                // Assert
                VerifyPackageSigningStatus(result, ValidationStatus.Succeeded, PackageSigningStatus.Valid);
                Assert.Empty(result.Issues);

                var allMessages = string.Join(Environment.NewLine, _logger.Messages);
                Assert.Contains("NU3018: The revocation function was unable to check revocation because the revocation server was offline.", allMessages);
                Assert.Contains("NU3018: The revocation function was unable to check revocation for the certificate.", allMessages);
            }
        }
コード例 #6
0
        public async Task RejectsUntrustedTimestampingCertificate()
        {
            // Arrange
            var testServer = await _fixture.GetTestServerAsync();

            var untrustedRootCa         = CertificateAuthority.Create(testServer.Url);
            var untrustedRootCertficate = new X509Certificate2(untrustedRootCa.Certificate.GetEncoded());
            var timestampService        = TimestampService.Create(untrustedRootCa);

            using (testServer.RegisterDefaultResponders(timestampService))
            {
                byte[] packageBytes;
                using (var temporaryTrust = new TrustedTestCert <X509Certificate2>(
                           untrustedRootCertficate,
                           x => x,
                           StoreName.Root,
                           StoreLocation.LocalMachine))
                {
                    packageBytes = await _fixture.GenerateSignedPackageBytesAsync(
                        TestResources.SignedPackageLeaf1,
                        await _fixture.GetSigningCertificateAsync(),
                        timestampService.Url,
                        _output);
                }

                TestUtility.RequireSignedPackage(_corePackageService,
                                                 TestResources.SignedPackageLeafId,
                                                 await _fixture.GetSigningCertificateThumbprintAsync());

                _packageStream = new MemoryStream(packageBytes);

                _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("NU3028", clientIssue.ClientCode);
                Assert.Equal(
                    "A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider.",
                    clientIssue.ClientMessage);
            }
        }
コード例 #7
0
        public async Task <UntrustedTimestampService> CreateUntrustedTimestampServiceAsync()
        {
            var testServer               = await _testServer.Value;
            var untrustedRootCa          = CertificateAuthority.Create(testServer.Url);
            var untrustedRootCertificate = untrustedRootCa.Certificate.ToX509Certificate2();
            var timestampService         = TimestampService.Create(untrustedRootCa);
            var responders               = testServer.RegisterDefaultResponders(timestampService);

            return(new UntrustedTimestampService(
                       untrustedRootCertificate,
                       timestampService.Url,
                       responders));
        }
コード例 #8
0
        public async Task <UntrustedSigningCertificate> CreateUntrustedSigningCertificateAsync()
        {
            var testServer               = await _testServer.Value;
            var untrustedRootCa          = CertificateAuthority.Create(testServer.Url);
            var untrustedRootCertificate = untrustedRootCa.Certificate.ToX509Certificate2();
            var responders               = testServer.RegisterRespondersForEntireChain(untrustedRootCa);

            var certificate = CreateSigningCertificate(untrustedRootCa);

            var disposable = new DisposableList <IDisposable> {
                untrustedRootCertificate, responders, certificate
            };

            return(new UntrustedSigningCertificate(untrustedRootCertificate, certificate, disposable));
        }
コード例 #9
0
        private async Task <CertificateAuthority> CreateDefaultTrustedRootCertificateAuthorityAsync()
        {
            var testServer = await GetTestServerAsync();

            var rootCa          = CertificateAuthority.Create(testServer.Url);
            var rootCertificate = new X509Certificate2(rootCa.Certificate.GetEncoded());

            _trustedRoot = new TrustedTestCert <X509Certificate2>(
                rootCertificate,
                certificate => certificate,
                StoreName.Root,
                StoreLocation.LocalMachine);

            return(rootCa);
        }
コード例 #10
0
        private async Task <CertificateAuthority> CreateDefaultTrustedRootCertificateAuthorityAsync()
        {
            var testServer = await GetTestServerAsync();

            var rootCa          = CertificateAuthority.Create(testServer.Url);
            var rootCertificate = rootCa.Certificate.ToX509Certificate2();

            _trustedRoot = new TrustedTestCert <X509Certificate2>(
                rootCertificate,
                certificate => certificate,
                StoreName.Root,
                StoreLocation.LocalMachine);

            _responders.AddRange(testServer.RegisterResponders(rootCa));

            return(rootCa);
        }
コード例 #11
0
        private CertificateAuthority CreateOfflineRevocationCA(ISigningTestServer testServer, DisposableList <IDisposable> responders)
        {
            var rootCa         = CertificateAuthority.Create(testServer.Url);
            var intermediateCa = rootCa.CreateIntermediateCertificateAuthority();

            var rootCertificate = new X509Certificate2(rootCa.Certificate.GetEncoded());

            var trustedServerRoot = TrustedTestCert.Create(
                rootCertificate,
                StoreName.Root,
                StoreLocation.LocalMachine);

            var ca = intermediateCa;

            while (ca != null)
            {
                responders.Add(testServer.RegisterResponder(ca));

                ca = ca.Parent;
            }

            return(intermediateCa);
        }
コード例 #12
0
        public async Task Timestamp_Verify_WithOfflineRevocation_ReturnsCorrectFlagsAndLogsAsync()
        {
            var nupkg = new SimpleTestPackageContext();

            using (var testServer = await SigningTestServer.CreateAsync())
                using (var responders = new DisposableList <IDisposable>())
                    using (var packageStream = await nupkg.CreateAsStreamAsync())
                        using (var testCertificate = new X509Certificate2(_trustedTestCert.Source.Cert))
                        {
                            CertificateAuthority rootCa         = CertificateAuthority.Create(testServer.Url);
                            CertificateAuthority intermediateCa = rootCa.CreateIntermediateCertificateAuthority();

                            responders.Add(testServer.RegisterResponder(intermediateCa));
                            responders.Add(testServer.RegisterResponder(rootCa));

                            using (var trustedServerRoot = TrustedTestCert.Create(
                                       new X509Certificate2(rootCa.Certificate.GetEncoded()),
                                       StoreName.Root,
                                       StoreLocation.LocalMachine))
                            {
                                var timestampService = TimestampService.Create(intermediateCa);

                                responders.Add(testServer.RegisterResponder(timestampService));

                                var timestampProvider = new Rfc3161TimestampProvider(timestampService.Url);

                                AuthorPrimarySignature signature = await SignedArchiveTestUtility.CreateAuthorSignatureForPackageAsync(testCertificate, packageStream, timestampProvider);

                                var timestamp = signature.Timestamps.First();

                                var settings = new SignedPackageVerifierSettings(
                                    allowUnsigned: false,
                                    allowUntrusted: false,
                                    allowIllegal: false,
                                    allowIgnoreTimestamp: false,
                                    allowMultipleTimestamps: false,
                                    allowNoTimestamp: false,
                                    allowUnknownRevocation: false,
                                    reportUnknownRevocation: true,
                                    verificationTarget: VerificationTarget.All,
                                    signaturePlacement: SignaturePlacement.Any,
                                    repositoryCountersignatureVerificationBehavior: SignatureVerificationBehavior.Always,
                                    revocationMode: RevocationMode.Online);

                                var logs = new List <SignatureLog>();

                                var result = timestamp.Verify(signature, settings, HashAlgorithmName.SHA256, logs);

                                result.HasFlag(SignatureVerificationStatusFlags.UnknownRevocation).Should().BeTrue();

                                var errors = logs.Where(l => l.Level == LogLevel.Error);
                                errors.Count().Should().Be(RuntimeEnvironmentHelper.IsWindows ? 2 : 1);

                                if (RuntimeEnvironmentHelper.IsWindows)
                                {
                                    errors.Should().Contain(w => w.Code == NuGetLogCode.NU3028 && w.Message.Contains("The revocation function was unable to check revocation because the revocation server could not be reached."));
                                    errors.Should().Contain(w => w.Code == NuGetLogCode.NU3028 && w.Message.Contains("The revocation function was unable to check revocation for the certificate."));
                                }
                                else
                                {
                                    errors.Should().Contain(w => w.Code == NuGetLogCode.NU3028 && w.Message.Contains("unable to get certificate CRL"));
                                }
                            }
                        }
        }