protected TestCertificatesHolder GenerateAndSaveSelfSignedCertificate(bool createNew = false) { var selfSignedCertificatePaths = _selfSignedCertificates; if (selfSignedCertificatePaths != null && createNew == false) { return(ReturnCertificatesHolder(selfSignedCertificatePaths)); } lock (typeof(TestBase)) { selfSignedCertificatePaths = _selfSignedCertificates; if (selfSignedCertificatePaths == null || createNew) { _selfSignedCertificates = selfSignedCertificatePaths = Generate(); } return(ReturnCertificatesHolder(selfSignedCertificatePaths)); } TestCertificatesHolder ReturnCertificatesHolder(TestCertificatesHolder certificates) { return(new TestCertificatesHolder(certificates, GetTempFileName)); } TestCertificatesHolder Generate() { var log = new StringBuilder(); byte[] certBytes; try { certBytes = CertificateUtils.CreateSelfSignedTestCertificate(Environment.MachineName, "RavenTestsServer", log); } catch (Exception e) { throw new CryptographicException($"Unable to generate the test certificate for the machine '{Environment.MachineName}'. Log: {log}", e); } X509Certificate2 serverCertificate; try { serverCertificate = new X509Certificate2(certBytes, (string)null, X509KeyStorageFlags.MachineKeySet); } catch (Exception e) { throw new CryptographicException($"Unable to load the test certificate for the machine '{Environment.MachineName}'. Log: {log}", e); } if (certBytes.Length == 0) { throw new CryptographicException($"Test certificate length is 0 bytes. Machine: '{Environment.MachineName}', Log: {log}"); } string serverCertificatePath = null; try { serverCertificatePath = Path.GetTempFileName(); File.WriteAllBytes(serverCertificatePath, certBytes); } catch (Exception e) { throw new InvalidOperationException("Failed to write the test certificate to a temp file." + $"tempFileName = {serverCertificatePath}" + $"certBytes.Length = {certBytes.Length}" + $"MachineName = {Environment.MachineName}.", e); } GlobalPathsToDelete.Add(serverCertificatePath); SecretProtection.ValidatePrivateKey(serverCertificatePath, null, certBytes, out var pk); var clientCertificate1Path = GenerateClientCertificate(1, serverCertificate, pk); var clientCertificate2Path = GenerateClientCertificate(2, serverCertificate, pk); var clientCertificate3Path = GenerateClientCertificate(3, serverCertificate, pk); return(new TestCertificatesHolder(serverCertificatePath, clientCertificate1Path, clientCertificate2Path, clientCertificate3Path)); } string GenerateClientCertificate(int index, X509Certificate2 serverCertificate, Org.BouncyCastle.Pkcs.AsymmetricKeyEntry pk) { CertificateUtils.CreateSelfSignedClientCertificate( $"{Environment.MachineName}_CC_{index}", new RavenServer.CertificateHolder { Certificate = serverCertificate, PrivateKey = pk }, out var certBytes, DateTime.UtcNow.Date.AddYears(5)); string clientCertificatePath = null; try { clientCertificatePath = Path.GetTempFileName(); File.WriteAllBytes(clientCertificatePath, certBytes); } catch (Exception e) { throw new InvalidOperationException("Failed to write the test certificate to a temp file." + $"tempFileName = {clientCertificatePath}" + $"certBytes.Length = {certBytes.Length}" + $"MachineName = {Environment.MachineName}.", e); } GlobalPathsToDelete.Add(clientCertificatePath); return(clientCertificatePath); } }
public TestCertificatesHolder GenerateAndSaveSelfSignedCertificate(bool createNew = false, [CallerMemberName] string caller = null) { if (createNew) { return(ReturnCertificatesHolder(Generate(caller, Interlocked.Increment(ref Counter)))); } var selfSignedCertificates = SelfSignedCertificates; if (selfSignedCertificates != null) { return(ReturnCertificatesHolder(selfSignedCertificates)); } lock (typeof(TestBase)) { selfSignedCertificates = SelfSignedCertificates; if (selfSignedCertificates == null) { SelfSignedCertificates = selfSignedCertificates = Generate(caller); } return(ReturnCertificatesHolder(selfSignedCertificates)); } TestCertificatesHolder ReturnCertificatesHolder(TestCertificatesHolder certificates) { return(new TestCertificatesHolder(certificates, _parent.GetTempFileName)); } TestCertificatesHolder Generate(string caller, int gen = 0) { var log = new StringBuilder(); byte[] certBytes; string serverCertificatePath = null; serverCertificatePath = Path.Combine(Path.GetTempPath(), $"Server-{gen}-{RavenVersionAttribute.Instance.Build}-{DateTime.Today:yyyy-MM-dd}.pfx"); if (File.Exists(serverCertificatePath) == false) { try { certBytes = CertificateUtils.CreateSelfSignedTestCertificate(Environment.MachineName, "RavenTestsServer", log); } catch (Exception e) { throw new CryptographicException($"Unable to generate the test certificate for the machine '{Environment.MachineName}'. Log: {log}", e); } if (certBytes.Length == 0) { throw new CryptographicException($"Test certificate length is 0 bytes. Machine: '{Environment.MachineName}', Log: {log}"); } try { File.WriteAllBytes(serverCertificatePath, certBytes); } catch (Exception e) { throw new InvalidOperationException("Failed to write the test certificate to a temp file." + $"tempFileName = {serverCertificatePath}" + $"certBytes.Length = {certBytes.Length}" + $"MachineName = {Environment.MachineName}.", e); } } else { certBytes = File.ReadAllBytes(serverCertificatePath); } X509Certificate2 serverCertificate; try { serverCertificate = new X509Certificate2(certBytes, (string)null, X509KeyStorageFlags.MachineKeySet); } catch (Exception e) { throw new CryptographicException($"Unable to load the test certificate for the machine '{Environment.MachineName}'. Log: {log}", e); } SecretProtection.ValidatePrivateKey(serverCertificatePath, null, certBytes, out var pk); SecretProtection.ValidateKeyUsages(serverCertificatePath, serverCertificate, validateKeyUsages: true); var clientCertificate1Path = GenerateClientCertificate(1, serverCertificate, pk); var clientCertificate2Path = GenerateClientCertificate(2, serverCertificate, pk); var clientCertificate3Path = GenerateClientCertificate(3, serverCertificate, pk); return(new TestCertificatesHolder(serverCertificatePath, clientCertificate1Path, clientCertificate2Path, clientCertificate3Path)); } string GenerateClientCertificate(int index, X509Certificate2 serverCertificate, Org.BouncyCastle.Pkcs.AsymmetricKeyEntry pk) { string name = $"{Environment.MachineName}_CC_{RavenVersionAttribute.Instance.Build}_{index}_{DateTime.Today:yyyy-MM-dd}"; string clientCertificatePath = Path.Combine(Path.GetTempPath(), name + ".pfx"); if (File.Exists(clientCertificatePath) == false) { CertificateUtils.CreateSelfSignedClientCertificate( name, new RavenServer.CertificateHolder { Certificate = serverCertificate, PrivateKey = pk }, out var certBytes, DateTime.UtcNow.Date.AddYears(5)); try { File.WriteAllBytes(clientCertificatePath, certBytes); } catch (Exception e) { throw new InvalidOperationException("Failed to write the test certificate to a temp file." + $"tempFileName = {clientCertificatePath}" + $"certBytes.Length = {certBytes.Length}" + $"MachineName = {Environment.MachineName}.", e); } } return(clientCertificatePath); } }