Beispiel #1
0
        public static string Encrypt(string srcDir)
        {
            var masterKey = Sodium.GenerateRandomBuffer((int)Sodium.crypto_aead_xchacha20poly1305_ietf_keybytes());
            var dstDir    = Path.Combine(Path.GetDirectoryName(srcDir), "Temp.Encryption");

            var srcOptions = StorageEnvironmentOptions.ForPath(srcDir);
            var dstOptions = StorageEnvironmentOptions.ForPath(dstDir);

            dstOptions.Encryption.MasterKey = masterKey;

            var protect = new SecretProtection(new SecurityConfiguration()).Protect(masterKey);

            StorageCompaction.Execute(srcOptions, (StorageEnvironmentOptions.DirectoryStorageEnvironmentOptions)dstOptions);

            using (var f = File.OpenWrite(Path.Combine(dstDir, SecretKeyEncrypted)))
            {
                f.Write(protect, 0, protect.Length);
                f.Flush();
            }

            IOExtensions.DeleteDirectory(srcDir);
            Directory.Move(dstDir, srcDir);

            return($"Encrypt: {Path.Combine(dstDir, SecretKeyEncrypted)} Created Successfully");
        }
Beispiel #2
0
        public static string PutKey(string destDir, string plainTextBase64KeyToPut)
        {
            var secret  = Convert.FromBase64String(plainTextBase64KeyToPut);
            var protect = new SecretProtection(new SecurityConfiguration()).Protect(secret);

            using (var f = File.OpenWrite(Path.Combine(destDir, SecretKeyEncrypted)))
            {
                f.Write(protect, 0, protect.Length);
                f.Flush();
            }

            return($"PutKey: {Path.Combine(destDir, SecretKeyEncrypted)} Created Successfully");
        }
Beispiel #3
0
        private static string RecoverServerStoreKey(string srcDir)
        {
            var keyPath = Path.Combine(srcDir, SecretKeyEncrypted);

            if (File.Exists(keyPath) == false)
            {
                throw new IOException("The key file " + keyPath + " doesn't exist. Either the Server Store is not encrypted or you provided a wrong path to the System folder");
            }

            var buffer = File.ReadAllBytes(keyPath);

            var key = new SecretProtection(new SecurityConfiguration()).Unprotect(buffer);

            return(Convert.ToBase64String(key));
        }
        private static string RecoverServerStoreKey(string srcDir)
        {
            var keyPath = Path.Combine(srcDir, SecretKeyEncrypted);

            if (File.Exists(keyPath) == false)
            {
                throw new IOException("File not exists:" + keyPath);
            }

            var buffer = File.ReadAllBytes(keyPath);

            var key = new SecretProtection(new SecurityConfiguration()).Unprotect(buffer);

            return(Convert.ToBase64String(key));
        }
Beispiel #5
0
        public static string PutKey(string destDir)
        {
            var base64Key = RecoverServerStoreKey(destDir);
            var entropy   = Sodium.GenerateRandomBuffer(256);
            var secret    = Convert.FromBase64String(base64Key);
            var protect   = new SecretProtection(new SecurityConfiguration()).Protect(secret, entropy);

            using (var f = File.OpenWrite(Path.Combine(destDir, SecretKeyEncrypted)))
            {
                f.Write(protect, 0, protect.Length);
                f.Write(entropy, 0, entropy.Length);
                f.Flush();
            }

            return($"PutKey: {Path.Combine(destDir, SecretKeyEncrypted)} Created Successfully");
        }
Beispiel #6
0
        private static string RecoverServerStoreKey(string srcDir)
        {
            var keyPath = Path.Combine(srcDir, SecretKeyEncrypted);

            if (File.Exists(keyPath) == false)
            {
                throw new IOException("File not exists:" + keyPath);
            }

            var buffer  = File.ReadAllBytes(keyPath);
            var secret  = new byte[buffer.Length - 32];
            var entropy = new byte[32];

            Array.Copy(buffer, 0, secret, 0, buffer.Length - 32);
            Array.Copy(buffer, buffer.Length - 32, entropy, 0, 32);

            var key = new SecretProtection(new SecurityConfiguration()).Unprotect(secret, entropy);

            return(Convert.ToBase64String(key));
        }
Beispiel #7
0
        public X509Certificate2 CreateAndPutExpiredClientCertificate(string serverCertPath, Dictionary <string, DatabaseAccess> permissions, SecurityClearance clearance = SecurityClearance.ValidUser)
        {
            var serverCertificate       = new X509Certificate2(serverCertPath, (string)null, X509KeyStorageFlags.MachineKeySet);
            var serverCertificateHolder = new SecretProtection(new SecurityConfiguration()).LoadCertificateFromPath(serverCertPath, null, Server.ServerStore);

            var clientCertificate = CertificateUtils.CreateSelfSignedExpiredClientCertificate("expired client cert", serverCertificateHolder);

            using (var store = GetDocumentStore(new Options
            {
                AdminCertificate = serverCertificate,
                ClientCertificate = serverCertificate
            }))
            {
                var requestExecutor = store.GetRequestExecutor();
                using (requestExecutor.ContextPool.AllocateOperationContext(out JsonOperationContext context))
                {
                    var command = new PutClientCertificateOperation("expired client cert", clientCertificate, permissions, clearance)
                                  .GetCommand(store.Conventions, context);

                    requestExecutor.Execute(command, context);
                }
            }
            return(clientCertificate);
        }
Beispiel #8
0
        public static string GetKey(string srcDir)
        {
            var masterKey = Sodium.GenerateMasterKey();
            var dstDir    = Path.Combine(Path.GetDirectoryName(srcDir), "Temp.Encryption");

            var srcOptions = StorageEnvironmentOptions.ForPath(srcDir);
            var dstOptions = StorageEnvironmentOptions.ForPath(dstDir);

            dstOptions.MasterKey = masterKey;

            var entropy = Sodium.GenerateRandomBuffer(256);
            var protect = new SecretProtection(new SecurityConfiguration()).Protect(masterKey, entropy);

            StorageCompaction.Execute(srcOptions, (StorageEnvironmentOptions.DirectoryStorageEnvironmentOptions)dstOptions);

            using (var f = File.OpenWrite(Path.Combine(dstDir, SecretKeyEncrypted)))
            {
                f.Write(protect, 0, protect.Length);
                f.Write(entropy, 0, entropy.Length);
                f.Flush();
            }

            return($"GetKey: {Path.Combine(dstDir, SecretKeyEncrypted)} Created Successfully");
        }
Beispiel #9
0
        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);
            }
        }
Beispiel #10
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);
        }
Beispiel #11
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);
        }
        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);
            }
        }