summaryrefslogtreecommitdiffstats
path: root/src/main.lib/Plugins/StorePlugins/PemFiles
diff options
context:
space:
mode:
authorWouterTinus <wouter.tinus@gmail.com>2019-09-07 01:36:12 +0200
committerWouterTinus <wouter.tinus@gmail.com>2019-09-07 01:36:12 +0200
commit7673fa357a81444cf6c216267dfab4e76684ba5c (patch)
tree73c0bd36e5b6261cd89a168c2a099f6556c59f4d /src/main.lib/Plugins/StorePlugins/PemFiles
parent42aa0faa4de6ea4184cfe1a5830508777418b11a (diff)
downloadletsencrypt-win-simple-7673fa357a81444cf6c216267dfab4e76684ba5c.zip
letsencrypt-win-simple-7673fa357a81444cf6c216267dfab4e76684ba5c.tar.gz
letsencrypt-win-simple-7673fa357a81444cf6c216267dfab4e76684ba5c.tar.bz2
move plugins & re-implement WebDav
Diffstat (limited to 'src/main.lib/Plugins/StorePlugins/PemFiles')
-rw-r--r--src/main.lib/Plugins/StorePlugins/PemFiles/PemFiles.cs118
-rw-r--r--src/main.lib/Plugins/StorePlugins/PemFiles/PemFilesArguments.cs7
-rw-r--r--src/main.lib/Plugins/StorePlugins/PemFiles/PemFilesArgumentsProvider.cs24
-rw-r--r--src/main.lib/Plugins/StorePlugins/PemFiles/PemFilesOptions.cs28
-rw-r--r--src/main.lib/Plugins/StorePlugins/PemFiles/PemFilesOptionsFactory.cs65
5 files changed, 242 insertions, 0 deletions
diff --git a/src/main.lib/Plugins/StorePlugins/PemFiles/PemFiles.cs b/src/main.lib/Plugins/StorePlugins/PemFiles/PemFiles.cs
new file mode 100644
index 0000000..ea7e79a
--- /dev/null
+++ b/src/main.lib/Plugins/StorePlugins/PemFiles/PemFiles.cs
@@ -0,0 +1,118 @@
+using Org.BouncyCastle.Pkcs;
+using PKISharp.WACS.DomainObjects;
+using PKISharp.WACS.Extensions;
+using PKISharp.WACS.Plugins.Interfaces;
+using PKISharp.WACS.Services;
+using System;
+using System.IO;
+using System.Linq;
+using System.Security.Cryptography.X509Certificates;
+
+namespace PKISharp.WACS.Plugins.StorePlugins
+{
+ internal class PemFiles : IStorePlugin
+ {
+ private readonly ILogService _log;
+ private readonly PemService _pemService;
+
+ private readonly string _path;
+
+ public PemFiles(
+ ILogService log, ISettingsService settings,
+ PemService pemService, PemFilesOptions options)
+ {
+ _log = log;
+ _pemService = pemService;
+ if (!string.IsNullOrWhiteSpace(options.Path))
+ {
+ _path = options.Path;
+ }
+ else
+ {
+ _path = settings.DefaultPemFilesPath;
+ }
+ if (_path.ValidPath(log))
+ {
+ _log.Debug("Using .pem certificate path: {_path}", _path);
+ }
+ else
+ {
+ throw new Exception($"Specified PemFiles path {_path} is not valid.");
+ }
+ }
+
+ public void Save(CertificateInfo input)
+ {
+ _log.Information("Exporting .pem files to {folder}", _path);
+ try
+ {
+ // Determine name
+ var name = input.SubjectName.Replace("*", "_");
+
+ // Base certificate
+ var certificateExport = input.Certificate.Export(X509ContentType.Cert);
+ var exportString = _pemService.GetPem("CERTIFICATE", certificateExport);
+ File.WriteAllText(Path.Combine(_path, $"{name}-crt.pem"), exportString);
+
+ // Rest of the chain
+ var chain = new X509Chain();
+ chain.Build(input.Certificate);
+ for (var i = 1; i < chain.ChainElements.Count; i++)
+ {
+ var chainCertificate = chain.ChainElements[i].Certificate;
+ // Do not include self-signed certificates, root certificates
+ // are supposed to be known already by the client.
+ if (chainCertificate.Subject != chainCertificate.Issuer)
+ {
+ var chainCertificateExport = chainCertificate.Export(X509ContentType.Cert);
+ exportString += _pemService.GetPem("CERTIFICATE", chainCertificateExport);
+ }
+ }
+
+ // Save complete chain
+ File.WriteAllText(Path.Combine(_path, $"{name}-chain.pem"), exportString);
+
+ // Private key
+ var pkPem = "";
+ var store = new Pkcs12Store(input.CacheFile.OpenRead(), input.CacheFilePassword.ToCharArray());
+ var alias = store.Aliases.OfType<string>().FirstOrDefault(p => store.IsKeyEntry(p));
+ var entry = store.GetKey(alias);
+ var key = entry.Key;
+ if (key.IsPrivate)
+ {
+ pkPem = _pemService.GetPem(entry.Key);
+ }
+ if (!string.IsNullOrEmpty(pkPem))
+ {
+ File.WriteAllText(Path.Combine(_path, $"{name}-key.pem"), pkPem);
+ }
+ else
+ {
+ _log.Warning("No private key found");
+ }
+
+ input.StoreInfo.Add(GetType(),
+ new StoreInfo()
+ {
+ Name = PemFilesOptions.PluginName,
+ Path = _path
+ });
+ }
+ catch (Exception ex)
+ {
+ _log.Error(ex, "Error exporting .pem files to folder");
+ }
+
+ }
+
+ public void Delete(CertificateInfo input)
+ {
+ // Not supported
+ }
+
+ public CertificateInfo FindByThumbprint(string thumbprint)
+ {
+ return null;
+ }
+ }
+}
diff --git a/src/main.lib/Plugins/StorePlugins/PemFiles/PemFilesArguments.cs b/src/main.lib/Plugins/StorePlugins/PemFiles/PemFilesArguments.cs
new file mode 100644
index 0000000..23370d6
--- /dev/null
+++ b/src/main.lib/Plugins/StorePlugins/PemFiles/PemFilesArguments.cs
@@ -0,0 +1,7 @@
+namespace PKISharp.WACS.Plugins.StorePlugins
+{
+ class PemFilesArguments
+ {
+ public string PemFilesPath { get; set; }
+ }
+}
diff --git a/src/main.lib/Plugins/StorePlugins/PemFiles/PemFilesArgumentsProvider.cs b/src/main.lib/Plugins/StorePlugins/PemFiles/PemFilesArgumentsProvider.cs
new file mode 100644
index 0000000..52368eb
--- /dev/null
+++ b/src/main.lib/Plugins/StorePlugins/PemFiles/PemFilesArgumentsProvider.cs
@@ -0,0 +1,24 @@
+using Fclp;
+using PKISharp.WACS.Configuration;
+
+namespace PKISharp.WACS.Plugins.StorePlugins
+{
+ class PemFilesArgumentsProvider : BaseArgumentsProvider<PemFilesArguments>
+ {
+ public override string Name => "PEM files plugin";
+ public override string Group => "Store";
+ public override string Condition => "--store pemfiles";
+
+ public override void Configure(FluentCommandLineParser<PemFilesArguments> parser)
+ {
+ parser.Setup(o => o.PemFilesPath)
+ .As("pemfilespath")
+ .WithDescription(".pem files are exported to this folder");
+ }
+
+ public override bool Active(PemFilesArguments current)
+ {
+ return !string.IsNullOrEmpty(current.PemFilesPath);
+ }
+ }
+}
diff --git a/src/main.lib/Plugins/StorePlugins/PemFiles/PemFilesOptions.cs b/src/main.lib/Plugins/StorePlugins/PemFiles/PemFilesOptions.cs
new file mode 100644
index 0000000..47e8ca3
--- /dev/null
+++ b/src/main.lib/Plugins/StorePlugins/PemFiles/PemFilesOptions.cs
@@ -0,0 +1,28 @@
+using PKISharp.WACS.Plugins.Base;
+using PKISharp.WACS.Plugins.Base.Options;
+using PKISharp.WACS.Services;
+
+namespace PKISharp.WACS.Plugins.StorePlugins
+{
+ [Plugin("e57c70e4-cd60-4ba6-80f6-a41703e21031")]
+ internal class PemFilesOptions : StorePluginOptions<PemFiles>
+ {
+ /// <summary>
+ /// Path to the .pem directory
+ /// </summary>
+ public string Path { get; set; }
+ internal const string PluginName = "PemFiles";
+ public override string Name { get => PluginName; }
+ public override string Description { get => "PEM encoded files (Apache, nginx, etc.)"; }
+
+ /// <summary>
+ /// Show details to the user
+ /// </summary>
+ /// <param name="input"></param>
+ public override void Show(IInputService input)
+ {
+ base.Show(input);
+ input.Show("Path", Path, level:1);
+ }
+ }
+}
diff --git a/src/main.lib/Plugins/StorePlugins/PemFiles/PemFilesOptionsFactory.cs b/src/main.lib/Plugins/StorePlugins/PemFiles/PemFilesOptionsFactory.cs
new file mode 100644
index 0000000..2dab221
--- /dev/null
+++ b/src/main.lib/Plugins/StorePlugins/PemFiles/PemFilesOptionsFactory.cs
@@ -0,0 +1,65 @@
+using PKISharp.WACS.Extensions;
+using PKISharp.WACS.Plugins.Base.Factories;
+using PKISharp.WACS.Services;
+using System;
+
+namespace PKISharp.WACS.Plugins.StorePlugins
+{
+ internal class PemFilesOptionsFactory : StorePluginOptionsFactory<PemFiles, PemFilesOptions>
+ {
+ private ILogService _log;
+ private IArgumentsService _arguments;
+ private ISettingsService _settings;
+
+ public PemFilesOptionsFactory(ILogService log, ISettingsService settings, IArgumentsService arguments)
+ {
+ _log = log;
+ _arguments = arguments;
+ _settings = settings;
+ }
+
+ public override PemFilesOptions Aquire(IInputService input, RunLevel runLevel)
+ {
+ var args = _arguments.GetArguments<PemFilesArguments>();
+ var path = args.PemFilesPath;
+ if (string.IsNullOrWhiteSpace(path))
+ {
+ path = _settings.DefaultPemFilesPath;
+ }
+ while (string.IsNullOrWhiteSpace(path) || !path.ValidPath(_log))
+ {
+ path = input.RequestString("Path to folder where .pem files are stored");
+ }
+ return Create(path);
+ }
+
+ public override PemFilesOptions Default()
+ {
+ var args = _arguments.GetArguments<PemFilesArguments>();
+ var path = _settings.DefaultPemFilesPath;
+ if (string.IsNullOrWhiteSpace(path))
+ {
+ path = _arguments.TryGetRequiredArgument(nameof(args.PemFilesPath), args.PemFilesPath);
+ }
+ if (path.ValidPath(_log))
+ {
+ return Create(path);
+ }
+ else
+ {
+ throw new Exception("Invalid path specified");
+ }
+ }
+
+ private PemFilesOptions Create(string path)
+ {
+ var ret = new PemFilesOptions();
+ if (!string.Equals(path, _settings.DefaultPemFilesPath, StringComparison.CurrentCultureIgnoreCase))
+ {
+ ret.Path = path;
+ }
+ return ret;
+ }
+ }
+
+} \ No newline at end of file