From 7f9eecbfe3aee828c18f127f9570a7e4ad22fac3 Mon Sep 17 00:00:00 2001 From: Joe VanWanzeele <76071503+joevanwanzeeleKF@users.noreply.github.com> Date: Wed, 21 Jun 2023 16:18:24 -0400 Subject: [PATCH] Include pem chain (#17) * updated to support 2 store types. HCVKV and HCV. * Updated to distinguish between multiple supported store types. * Fixed store path and mount point mapping * updated doc to reflect multiple store type configs. * removed sensitive info from tracelog. * Fixed issue with path not being resolved before attempting to write cert. * Removed KEY_SECRET from PutCertificate Task * Modified PutCertificate to include ---BEGIN ----END banners (for key+cert) * Allows for Recursive subfolder inventory * Update readme to call out cert store limits * Adding InputValidation for KeyValue secrets * including certificate chain when enrolling via platform. * added flag on store type to indicate whether to include cert chain * fixed issue when checking for revocation time for inventory. --- README.md | 4 +- .../HcvKeyValueClient.cs | 59 +++++++++++++----- .../HcvKeyfactorClient.cs | 5 +- hashicorp-vault-orchestrator/IHashiClient.cs | 2 +- hashicorp-vault-orchestrator/Jobs/JobBase.cs | 13 ++-- .../Jobs/Management.cs | 2 +- images/store_type_fields.png | Bin 15612 -> 17863 bytes readme_source.md | 4 +- 8 files changed, 58 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index cf5aba7..bf2dcfb 100644 --- a/README.md +++ b/README.md @@ -79,9 +79,10 @@ This integration was built on the .NET Core 3.1 target framework and are compati 1. It is not necessary to use the Vault root token when creating a Certificate Store for HashicorpVault. We recommend creating a token with policies that reflect the minimum permissions necessary to perform the intended operations. -1. For the Key-Value secrets engine, the certificates are stored as an entry with 2 fields. +1. For the Key-Value secrets engine, the certificates are stored as an entry with these fields. - `PUBLIC_KEY` - The certificate public key +- `PUBLIC_KEY_` - The nth certificate in the chain - `PRIVATE_KEY` - The certificate private key **Note**: Key/Value secrets that do not include these keys (PUBLIC_KEY, and PRIVATE_KEY), will be ignored during inventory scans. @@ -126,6 +127,7 @@ This integration was built on the .NET Core 3.1 target framework and are compati - **VaultServerUrl** - type: *string*, *required* - **VaultToken** - type: *secret*, *required* - **SubfolderInventory** - type: *bool* (By default, this is set to false. Not a required field) + - **IncludeCertChain** - type: *bool* (If true, the available intermediate certificates will also be written to Vault during enrollment) ![](images/store_type_fields.png) diff --git a/hashicorp-vault-orchestrator/HcvKeyValueClient.cs b/hashicorp-vault-orchestrator/HcvKeyValueClient.cs index 131f46d..6796217 100644 --- a/hashicorp-vault-orchestrator/HcvKeyValueClient.cs +++ b/hashicorp-vault-orchestrator/HcvKeyValueClient.cs @@ -39,7 +39,7 @@ public class HcvKeyValueClient : IHashiClient //private VaultClientSettings clientSettings { get; set; } - public HcvKeyValueClient(string vaultToken, string serverUrl, string mountPoint, string storePath,bool SubfolderInventory = false) + public HcvKeyValueClient(string vaultToken, string serverUrl, string mountPoint, string storePath, bool SubfolderInventory = false) { // Initialize one of the several auth methods. IAuthMethodInfo authMethod = new TokenAuthMethodInfo(vaultToken); @@ -54,7 +54,7 @@ public HcvKeyValueClient(string vaultToken, string serverUrl, string mountPoint, public async Task> ListComponentPathsAsync(string storagePath) { VaultClient.V1.Auth.ResetVaultToken(); - List componentPaths = new List {}; + List componentPaths = new List { }; try { Secret listInfo = (await VaultClient.V1.Secrets.KeyValue.V2.ReadSecretPathsAsync(storagePath, _mountPoint)); @@ -89,8 +89,6 @@ public async Task GetCertificate(string key) var relativePath = fullPath.Substring(_storePath.Length); try { - - try { if (_mountPoint == null) @@ -188,7 +186,7 @@ public async Task> GetVaults() return vaults; } - public async Task PutCertificate(string certName, string contents, string pfxPassword) + public async Task PutCertificate(string certName, string contents, string pfxPassword, bool includeChain) { VaultClient.V1.Auth.ResetVaultToken(); @@ -215,13 +213,12 @@ public async Task PutCertificate(string certName, string contents, string pfxPas alias = p.Aliases.Cast().SingleOrDefault(a => p.IsKeyEntry(a)); logger.LogTrace($"Alias = {alias}"); var publicKey = p.GetCertificate(alias).Certificate.GetPublicKey(); + logger.LogTrace($"publicKey = {publicKey}"); var KeyEntry = p.GetKey(alias); - // logger.LogTrace($"KeyEntry = {KeyEntry}"); if (KeyEntry == null) throw new Exception("Unable to retrieve private key"); var privateKey = KeyEntry.Key; - // logger.LogTrace($"privateKey = {privateKey}"); var keyPair = new AsymmetricCipherKeyPair(publicKey, privateKey); pemWriter.WriteObject(keyPair.Private); @@ -235,12 +232,40 @@ public async Task PutCertificate(string certName, string contents, string pfxPas logger.LogTrace("Finished Extracting Private Key..."); } } - var pubCertPem = Pemify(Convert.ToBase64String(p.GetCertificate(alias).Certificate.GetEncoded())); + + var pubCert = p.GetCertificate(alias).Certificate.GetEncoded(); + var pubCertPem = Pemify(Convert.ToBase64String(pubCert)); + + // add the certs in the chain + + var pemChain = new List(); + var chain = p.GetCertificateChain(alias).ToList(); + + chain.ForEach(c => + { + var cert = c.Certificate.GetEncoded(); + var encoded = Pemify(Convert.ToBase64String(cert)); + pemChain.Add(encoded); + }); try { certDict.Add("PRIVATE_KEY", privateKeyString); certDict.Add("PUBLIC_KEY", pubCertPem); + + if (includeChain) + { + var i = 1; + pemChain.ForEach(pc => + { + if (pc != pubCertPem) + { + certDict.Add($"PUBLIC_KEY_{i}", pc); + i++; + } + }); + + } } catch (Exception ex) { @@ -248,7 +273,7 @@ public async Task PutCertificate(string certName, string contents, string pfxPas throw; } try - { + { var fullPath = _storePath + certName; if (_mountPoint == null) @@ -297,8 +322,8 @@ public async Task> GetCertificates() VaultClient.V1.Auth.ResetVaultToken(); _storePath = _storePath.TrimStart('/'); List subPaths = new List(); - //Grabs the list of subpaths to get certificates from, if SubFolder Inventory is turned on. - //Otherwise just define the single path _storePath + //Grabs the list of subpaths to get certificates from, if SubFolder Inventory is turned on. + //Otherwise just define the single path _storePath if (_subfolderInventory == true) { subPaths = (await ListComponentPathsAsync(_storePath)); @@ -325,12 +350,12 @@ public async Task> GetCertificates() { certNames = (await VaultClient.V1.Secrets.KeyValue.V2.ReadSecretPathsAsync(path, mountPoint: _mountPoint)).Data.Keys.ToList(); } - - certNames.ForEach(k => - { - var cert = GetCertificate($"{relative_path}{k}").Result; - if (cert != null) certs.Add(cert); - }); + + certNames.ForEach(k => + { + var cert = GetCertificate($"{relative_path}{k}").Result; + if (cert != null) certs.Add(cert); + }); } catch (Exception ex) { diff --git a/hashicorp-vault-orchestrator/HcvKeyfactorClient.cs b/hashicorp-vault-orchestrator/HcvKeyfactorClient.cs index 4d2f2b7..e97768a 100644 --- a/hashicorp-vault-orchestrator/HcvKeyfactorClient.cs +++ b/hashicorp-vault-orchestrator/HcvKeyfactorClient.cs @@ -66,8 +66,9 @@ public async Task GetCertificate(string key) string revokeTime; content.data.TryGetValue("revocation_time", out revokeTime); + - if (revokeTime.Equals(0)) + if (revokeTime.Equals("0")) { var inventoryItem = new CurrentInventoryItem() { @@ -130,7 +131,7 @@ public Task> GetVaults() throw new NotSupportedException(); } - public Task PutCertificate(string certName, string contents, string pfxPassword) + public Task PutCertificate(string certName, string contents, string pfxPassword, bool includeChain) { throw new NotSupportedException(); } diff --git a/hashicorp-vault-orchestrator/IHashiClient.cs b/hashicorp-vault-orchestrator/IHashiClient.cs index fbee83e..043dd63 100644 --- a/hashicorp-vault-orchestrator/IHashiClient.cs +++ b/hashicorp-vault-orchestrator/IHashiClient.cs @@ -16,7 +16,7 @@ public interface IHashiClient Task> GetCertificates(); Task GetCertificate(string key); Task> GetVaults(); - Task PutCertificate(string certName, string contents, string pfxPassword); + Task PutCertificate(string certName, string contents, string pfxPassword, bool includeChain); Task DeleteCertificate(string certName); } } diff --git a/hashicorp-vault-orchestrator/Jobs/JobBase.cs b/hashicorp-vault-orchestrator/Jobs/JobBase.cs index a3345b8..83e8eb7 100644 --- a/hashicorp-vault-orchestrator/Jobs/JobBase.cs +++ b/hashicorp-vault-orchestrator/Jobs/JobBase.cs @@ -24,6 +24,8 @@ public abstract class JobBase public bool SubfolderInventory { get; set; } + public bool IncludeCertChain { get; set; } + public string MountPoint { get; set; } // the mount point of the KV secrets engine. defaults to KV public string RoleName { get; set; } @@ -71,14 +73,9 @@ private void InitProps(dynamic props, string capability) VaultServerUrl = props["VaultServerUrl"]; SecretsEngine = props["SecretsEngine"]; MountPoint = props["MountPoint"] ?? null; - if (props["SubfolderInventory"] == null) - { - SubfolderInventory = false; - } - else - { - SubfolderInventory = props["SubfolderInventory"]; - } + + SubfolderInventory = props["SubfolderInventory"] ?? false; + IncludeCertChain = props["IncludeCertChain"] ?? false; var isPki = capability.Contains("HCVPKI"); diff --git a/hashicorp-vault-orchestrator/Jobs/Management.cs b/hashicorp-vault-orchestrator/Jobs/Management.cs index 90e4bd8..0670d32 100644 --- a/hashicorp-vault-orchestrator/Jobs/Management.cs +++ b/hashicorp-vault-orchestrator/Jobs/Management.cs @@ -57,7 +57,7 @@ protected virtual JobResult PerformAddition(string alias, string pfxPassword, st try { // uploadCollection is either not null or an exception was thrown. - var cert = VaultClient.PutCertificate(alias, entryContents, pfxPassword); + var cert = VaultClient.PutCertificate(alias, entryContents, pfxPassword, IncludeCertChain); complete.Result = OrchestratorJobStatusJobResult.Success; } catch (Exception ex) diff --git a/images/store_type_fields.png b/images/store_type_fields.png index 2944946448a4a14da30ca90d640518b308446493..c727456ca20e2c6ffea41bf9ffa056fb612f83e0 100644 GIT binary patch literal 17863 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 C!mJwr literal 15612 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 - The nth certificate in the chain - `PRIVATE_KEY` - The certificate private key **Note**: Key/Value secrets that do not include these keys (PUBLIC_KEY, and PRIVATE_KEY), will be ignored during inventory scans. @@ -83,6 +84,7 @@ This integration was built on the .NET Core 3.1 target framework and are compati - **VaultServerUrl** - type: *string*, *required* - **VaultToken** - type: *secret*, *required* - **SubfolderInventory** - type: *bool* (By default, this is set to false. Not a required field) + - **IncludeCertChain** - type: *bool* (If true, the available intermediate certificates will also be written to Vault during enrollment) ![](images/store_type_fields.png)