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