示例#1
0
        public Task GetHosts()
        {
            AssertOnlyInSetupMode();

            using (ServerStore.ContextPool.AllocateOperationContext(out JsonOperationContext context))
                using (var certificateJson = context.ReadForMemory(RequestBodyStream(), "setup-certificate"))
                {
                    var certDef = JsonDeserializationServer.CertificateDefinition(certificateJson);

                    X509Certificate2 certificate = null;
                    string           cn;

                    try
                    {
                        certificate = certDef.Password == null
                        ? new X509Certificate2(Convert.FromBase64String(certDef.Certificate))
                        : new X509Certificate2(Convert.FromBase64String(certDef.Certificate), certDef.Password);

                        cn = certificate.GetNameInfo(X509NameType.DnsName, false);
                    }
                    catch (Exception e)
                    {
                        throw new BadRequestException($"Failed to extract the CN property from the certificate {certificate?.FriendlyName}. Maybe the password is wrong?", e);
                    }

                    try
                    {
                        SecretProtection.ValidateKeyUsages("Setup Wizard", certificate);
                    }
                    catch (Exception e)
                    {
                        throw new InvalidOperationException($"Failed to load the uploaded certificate. Did you accidently upload a client certificate?", e);
                    }

                    using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream()))
                    {
                        writer.WriteStartObject();
                        writer.WritePropertyName("CN");
                        writer.WriteString(cn);
                        writer.WriteComma();
                        writer.WritePropertyName("AlternativeNames");
                        writer.WriteStartArray();

                        var first = true;
                        foreach (var value in SetupManager.GetCertificateAlternativeNames(certificate))
                        {
                            if (first == false)
                            {
                                writer.WriteComma();
                            }
                            first = false;

                            writer.WriteString(value);
                        }

                        writer.WriteEndArray();

                        writer.WriteEndObject();
                    }
                }

            return(Task.CompletedTask);
        }
示例#2
0
        public Task GetHosts()
        {
            AssertOnlyInSetupMode();

            using (ServerStore.ContextPool.AllocateOperationContext(out JsonOperationContext context))
                using (var certificateJson = context.ReadForMemory(RequestBodyStream(), "setup-certificate"))
                {
                    var certDef = JsonDeserializationServer.CertificateDefinition(certificateJson);

                    X509Certificate2 certificate = null;
                    string           cn;

                    try
                    {
                        certificate = certDef.Password == null
                        ? new X509Certificate2(Convert.FromBase64String(certDef.Certificate), (string)null, X509KeyStorageFlags.MachineKeySet)
                        : new X509Certificate2(Convert.FromBase64String(certDef.Certificate), certDef.Password, X509KeyStorageFlags.MachineKeySet);

                        cn = certificate.GetNameInfo(X509NameType.SimpleName, false);
                    }
                    catch (Exception e)
                    {
                        throw new BadRequestException($"Failed to extract the CN property from the certificate {certificate?.FriendlyName}. Maybe the password is wrong?", e);
                    }

                    if (cn == null)
                    {
                        throw new BadRequestException($"Failed to extract the CN property from the certificate. CN is null");
                    }

                    if (cn.LastIndexOf('*') > 0)
                    {
                        throw new NotSupportedException("The wildcard CN name contains a '*' which is not at the first character of the string. It is not supported in the Setup Wizard, you can do a manual setup instead.");
                    }

                    try
                    {
                        SecretProtection.ValidateKeyUsages("Setup Wizard", certificate);
                    }
                    catch (Exception e)
                    {
                        throw new InvalidOperationException($"Failed to load the uploaded certificate. Did you accidentally upload a client certificate?", e);
                    }

                    using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream()))
                    {
                        writer.WriteStartObject();
                        writer.WritePropertyName("CN");
                        writer.WriteString(cn);
                        writer.WriteComma();
                        writer.WritePropertyName("AlternativeNames");
                        writer.WriteStartArray();

                        var first = true;
                        foreach (var value in SetupManager.GetCertificateAlternativeNames(certificate))
                        {
                            if (first == false)
                            {
                                writer.WriteComma();
                            }
                            first = false;

                            writer.WriteString(value);
                        }

                        writer.WriteEndArray();

                        writer.WriteEndObject();
                    }
                }

            return(Task.CompletedTask);
        }
        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);
            }
        }