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