Beispiel #1
0
        private static void ValidateExpiration(string source, X509Certificate2 loadedCertificate, ServerStore serverStore)
        {
            if (loadedCertificate.NotAfter < DateTime.UtcNow)
            {
                if (Logger.IsOperationsEnabled)
                {
                    Logger.Operations($"The provided certificate {loadedCertificate.FriendlyName} from {source} is expired! Thubprint: {loadedCertificate.Thumbprint}, Expired on: {loadedCertificate.NotAfter}");
                }
            }


            if (serverStore.LicenseManager.GetLicenseStatus().Type == LicenseType.Developer)
            {
                // Do not allow long range certificates in developer mode.
                if (loadedCertificate.NotAfter > DateTime.UtcNow.AddMonths(4))
                {
                    const string msg = "The server certificate expiration date is more than 4 months from now. " +
                                       "This is not allowed when using the developer license. " +
                                       "The developer license is not allowed for production use. " +
                                       "Either switch the license or use a short term certificate.";

                    if (Logger.IsOperationsEnabled)
                    {
                        Logger.Operations(msg);
                    }
                    throw new InvalidOperationException(msg);
                }
            }
        }
Beispiel #2
0
        public static RavenServer.CertificateHolder ValidateCertificateAndCreateCertificateHolder(string source, X509Certificate2 loadedCertificate, byte[] rawBytes, string password, ServerStore serverStore)
        {
            ValidateExpiration(source, loadedCertificate, serverStore);

            ValidatePrivateKey(source, password, rawBytes, out var privateKey);

            ValidateKeyUsages(source, loadedCertificate);

            AddCertificateChainToTheUserCertificateAuthority(loadedCertificate, rawBytes, password);


            return(new RavenServer.CertificateHolder
            {
                Certificate = loadedCertificate,
                CertificateForClients = Convert.ToBase64String(loadedCertificate.Export(X509ContentType.Cert)),
                PrivateKey = privateKey
            });
        }
Beispiel #3
0
        public RavenServer.CertificateHolder LoadCertificateFromPath(string path, string password, ServerStore serverStore)
        {
            try
            {
                path = Path.Combine(AppContext.BaseDirectory, path);
                var rawData = File.ReadAllBytes(path);

                // we need to load it as exportable because we might need to send it over the cluster
                var loadedCertificate = new X509Certificate2(rawData, password, X509KeyStorageFlags.Exportable);

                ValidateExpiration(path, loadedCertificate, serverStore);

                ValidatePrivateKey(path, password, rawData, out var privateKey);

                ValidateKeyUsages(path, loadedCertificate);

                return(new RavenServer.CertificateHolder
                {
                    Certificate = loadedCertificate,
                    CertificateForClients = Convert.ToBase64String(loadedCertificate.Export(X509ContentType.Cert)),
                    PrivateKey = privateKey
                });
            }
            catch (Exception e)
            {
                throw new InvalidOperationException($"Could not load certificate file {path}", e);
            }
        }
Beispiel #4
0
        public RavenServer.CertificateHolder LoadCertificateWithExecutable(string executable, string args, ServerStore serverStore)
        {
            var process = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    FileName               = executable,
                    Arguments              = args,
                    UseShellExecute        = false,
                    RedirectStandardOutput = true,
                    RedirectStandardError  = true,
                    CreateNoWindow         = true
                }
            };

            var sw = Stopwatch.StartNew();

            try
            {
                process.Start();
            }
            catch (Exception e)
            {
                throw new InvalidOperationException($"Unable to get certificate by executing {executable} {args}. Failed to start process.", e);
            }

            var ms         = new MemoryStream();
            var readErrors = process.StandardError.ReadToEndAsync();
            var readStdOut = process.StandardOutput.BaseStream.CopyToAsync(ms);

            string GetStdError()
            {
                try
                {
                    return(readErrors.Result);
                }
                catch
                {
                    return("Unable to get stderr");
                }
            }

            if (process.WaitForExit((int)_config.CertificateExecTimeout.AsTimeSpan.TotalMilliseconds) == false)
            {
                process.Kill();
                throw new InvalidOperationException($"Unable to get certificate by executing {executable} {args}, waited for {_config.CertificateExecTimeout} ms but the process didn't exit. Stderr: {GetStdError()}");
            }
            try
            {
                readStdOut.Wait(_config.CertificateExecTimeout.AsTimeSpan);
                readErrors.Wait(_config.CertificateExecTimeout.AsTimeSpan);
            }
            catch (Exception e)
            {
                throw new InvalidOperationException(
                          $"Unable to get certificate by executing {executable} {args}, waited for {_config.CertificateExecTimeout} ms but the process didn't exit. Stderr: {GetStdError()}",
                          e);
            }

            if (Logger.IsOperationsEnabled)
            {
                var errors = GetStdError();
                Logger.Operations(string.Format($"Executing {executable} {args} took {sw.ElapsedMilliseconds:#,#;;0} ms"));
                if (!string.IsNullOrWhiteSpace(errors))
                {
                    Logger.Operations(string.Format($"Executing {executable} {args} finished with exit code: {process.ExitCode}. Errors: {errors}"));
                }
            }

            if (process.ExitCode != 0)
            {
                throw new InvalidOperationException(
                          $"Unable to get certificate by executing {executable} {args}, the exit code was {process.ExitCode}. Stderr: {GetStdError()}");
            }

            var rawData = ms.ToArray();
            X509Certificate2   loadedCertificate;
            AsymmetricKeyEntry privateKey;

            try
            {
                // may need to send this over the cluster, so use exportable here
                loadedCertificate = new X509Certificate2(rawData, (string)null, X509KeyStorageFlags.Exportable);
                ValidateExpiration(executable, loadedCertificate, serverStore);
                ValidatePrivateKey(executable, null, rawData, out privateKey);
                ValidateKeyUsages(executable, loadedCertificate);
            }
            catch (Exception e)
            {
                throw new InvalidOperationException($"Got invalid certificate via {executable} {args}", e);
            }

            return(new RavenServer.CertificateHolder
            {
                Certificate = loadedCertificate,
                CertificateForClients = Convert.ToBase64String(loadedCertificate.Export(X509ContentType.Cert)),
                PrivateKey = privateKey
            });
        }