diff options
author | WouterTinus <wouter.tinus@gmail.com> | 2019-09-07 01:36:12 +0200 |
---|---|---|
committer | WouterTinus <wouter.tinus@gmail.com> | 2019-09-07 01:36:12 +0200 |
commit | 7673fa357a81444cf6c216267dfab4e76684ba5c (patch) | |
tree | 73c0bd36e5b6261cd89a168c2a099f6556c59f4d /src/main.lib/Plugins/StorePlugins/PemFiles | |
parent | 42aa0faa4de6ea4184cfe1a5830508777418b11a (diff) | |
download | letsencrypt-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')
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 |