diff --git a/CitrixAdcOrchestratorJobExtension/CitrixAdcStore.cs b/CitrixAdcOrchestratorJobExtension/CitrixAdcStore.cs index 180e81c..500cfee 100644 --- a/CitrixAdcOrchestratorJobExtension/CitrixAdcStore.cs +++ b/CitrixAdcOrchestratorJobExtension/CitrixAdcStore.cs @@ -759,120 +759,52 @@ public X509Certificate2 GetX509Certificate(sslcertkey certificate) { Logger.MethodEntry(LogLevel.Debug); - systemfile f; - string[] privateKeyDelims = new string[3] { "-----BEGIN RSA PRIVATE KEY-----", "-----BEGIN PRIVATE KEY-----", "-----BEGIN ENCRYPTED PRIVATE KEY-----" }; - string certString = null; - string keyString = null; + X509Certificate2 x509Cert = null; try { - Logger.LogTrace($"Trying GetSystemFile(fileLocation): {fileLocation}"); - f = GetSystemFile(fileLocation); - Logger.LogTrace($"Finished GetSystemFile(fileLocation): {fileLocation}"); - } - catch - { - Logger.LogError("Error Occurred in GetSystemFile(fileLocation)"); - hasKey = false; - return null; - } + Logger.LogTrace($"Trying GetSystemFile(fileLocation): {certificate.cert}"); + systemfile f = GetSystemFile(certificate.cert); + Logger.LogTrace($"Finished GetSystemFile(fileLocation): {certificate.cert}"); - //Ignore Directories - if (f.filemode != null && f.filemode[0].ToUpper() == "DIRECTORY") - { - hasKey = false; - return null; - } - - // Determine if it's a cert - X509Certificate2 x = null; - try - { var b = Convert.FromBase64String(f.filecontent); var fileString = Encoding.Default.GetString(b); - // Check if private key is included with certificate - var privateKeyIdx = -1; - foreach(string privateKeyDelim in privateKeyDelims) - { - if (fileString.IndexOf(privateKeyDelim, StringComparison.Ordinal) >= 0) - privateKeyIdx = Array.IndexOf(privateKeyDelims, privateKeyDelim); - } - - var containsCert = fileString.IndexOf("-----BEGIN CERTIFICATE-----", StringComparison.Ordinal) >= 0; + string endDelim = "-----END CERTIFICATE-----"; + int startIdx = fileString.IndexOf("-----BEGIN CERTIFICATE-----", StringComparison.Ordinal); + int endIdx = fileString.IndexOf(endDelim, StringComparison.Ordinal); - Logger.LogTrace($"containsKey: {privateKeyIdx > -1} containsCert: {containsCert}"); - - if (containsCert && privateKeyIdx > -1) - { - Logger.LogTrace($"File contains certificate and key: {fileLocation}"); - - var keyStart = fileString.IndexOf(privateKeyDelims[privateKeyIdx], StringComparison.Ordinal); - var keyEnd = fileString.IndexOf(privateKeyDelims[privateKeyIdx].Replace("BEGIN","END"), StringComparison.Ordinal) + - privateKeyDelims[privateKeyIdx].Replace("BEGIN", "END").Length; - - // check if need to remove new line - keyString = fileString.Substring(keyStart, keyEnd - keyStart); - certString = fileString.Remove(keyStart, keyEnd - keyStart); - } - else if (containsCert) + if (startIdx == -1 || endIdx == -1) { - Logger.LogTrace("containsCert"); - certString = fileString; - // check .key file - try - { - var fileNameWithoutExtension = fileLocation; - if (fileLocation.EndsWith(".crt",StringComparison.CurrentCultureIgnoreCase) || - fileLocation.EndsWith(".cer", StringComparison.CurrentCultureIgnoreCase) || - fileLocation.EndsWith(".pem", StringComparison.CurrentCultureIgnoreCase) || - fileLocation.EndsWith(".pfx", StringComparison.CurrentCultureIgnoreCase) || - fileLocation.EndsWith(".cert", StringComparison.CurrentCultureIgnoreCase) || - fileLocation.EndsWith(".der", StringComparison.CurrentCultureIgnoreCase)) - { - fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileLocation); - } - var keyFile = GetSystemFile(fileNameWithoutExtension + ".key"); - keyString = Encoding.UTF8.GetString(Convert.FromBase64String(keyFile.filecontent)); - } - catch (Exception e) - { - Logger.LogError("Unable to evaluate private key - " + LogHandler.FlattenException(e)); - } + Logger.LogWarning($"Certificate {certificate.certkey} does not contain a valid PEM formatted certificate"); } + certString = fileString.Substring(startIdx, endIdx - startIdx + endDelim.Length); + if (certString == null) { - hasKey = false; return null; } try { - x = ReadX509Certificate(certString); + x509Cert = ReadX509Certificate(certString); } catch (Exception e) { - // Not a certificate file - Logger.LogError($"Error reading x509Certificate at {fileLocation}"); - Logger.LogError(LogHandler.FlattenException(e)); - hasKey = false; + Logger.LogError($"Error reading converting {certificate.certkey} to X509 certificate format: {LogHandler.FlattenException(e)}"); return null; } - - hasKey = !string.IsNullOrEmpty(keyString); } catch (Exception e) { // Not a certificate file - Logger.LogError($"{fileLocation} is not a certificate"); - Logger.LogError(LogHandler.FlattenException(e)); - hasKey = false; + Logger.LogError($"Error reading/processing certificate {certificate.certkey}: {LogHandler.FlattenException(e)}"); } Logger.MethodExit(LogLevel.Debug); - return x; + return x509Cert; } private systemfile GetSystemFile(string fileName) diff --git a/CitrixAdcOrchestratorJobExtension/Inventory.cs b/CitrixAdcOrchestratorJobExtension/Inventory.cs index cc5b837..18f01ad 100644 --- a/CitrixAdcOrchestratorJobExtension/Inventory.cs +++ b/CitrixAdcOrchestratorJobExtension/Inventory.cs @@ -94,39 +94,17 @@ private JobResult ProcessJob(CitrixAdcStore store, InventoryJobConfiguration job foreach (sslcertkey certificate in certificates) { _logger.LogDebug($"Retrieving certificate file: {certificate.cert} for alias {certificate.certkey}"); - X509Certificate2 x = store.GetX509Certificate(s, out bool privateKeyEntry); + X509Certificate2 x = store.GetX509Certificate(certificate); if (x == null) continue; - _logger.LogTrace($"##### privateKeyEntry: {privateKeyEntry.ToString()}"); - if (!privateKeyEntry) - { - var certKey = keyPairList.FirstOrDefault(p => p.cert == s); - _logger.LogTrace($"##### certKey: {certKey}"); - privateKeyEntry = certKey != null && !string.IsNullOrEmpty(certKey.key); - } - _logger.LogTrace($"##### privateKeyEntry: {privateKeyEntry.ToString()}"); - - processedAliases.Add(s); - Dictionary parameters = new Dictionary(); - string tempStorePath = store.StorePath.Substring(store.StorePath.Length-1,1) == "/" ? store.StorePath : store.StorePath + "/"; - var containsKeyWithPath = keyPairMap.ContainsKey(tempStorePath + s); - var containsKey = keyPairMap.ContainsKey(s); - - _logger.LogTrace($"##### containsKeyWithPath: {containsKeyWithPath.ToString()}"); - _logger.LogTrace($"##### containsKey: {containsKey.ToString()}"); - - - if (containsKey || containsKeyWithPath) + if (certificate.key != null) { - var keyPairName = containsKeyWithPath ? keyPairMap[tempStorePath + s] : keyPairMap[s]; - - _logger.LogDebug($"Found keyPairName: {keyPairName}"); - parameters.Add("keyPairName", keyPairName); + parameters.Add("keyPairName", certificate.certkey); - var binding = store.GetBinding(keyPairName); + var binding = store.GetBinding(certificate.certkey); var vserverBindings = binding?.sslcertkey_sslvserver_binding; if (vserverBindings != null) @@ -140,7 +118,7 @@ private JobResult ProcessJob(CitrixAdcStore store, InventoryJobConfiguration job foreach (string server in virtualServerName.Split(',')) { var bindings = store.GetBindingByVServer(server); - var first = bindings.FirstOrDefault(b => b.certkeyname == keyPairName); + var first = bindings.FirstOrDefault(b => b.certkeyname == certificate.certkey); if (first != null) bindingsCsv += first.snicert + ","; } parameters.Add("sniCert", bindingsCsv.TrimEnd(',')); @@ -155,18 +133,16 @@ private JobResult ProcessJob(CitrixAdcStore store, InventoryJobConfiguration job inventory.Add(new CurrentInventoryItem() { - Alias = s, + Alias = certificate.certkey, Certificates = new[] { Convert.ToBase64String(x.GetRawCertData()) }, - //ItemStatus = itemStatus, - PrivateKeyEntry = privateKeyEntry, + PrivateKeyEntry = certificate.key != null, UseChainLevel = false, Parameters = parameters }); } _logger.LogDebug($"Found {inventory.Count} certificates at {jobConfiguration.CertificateStoreDetails.StorePath}"); - - } + catch (Exception ex) { _logger.LogError("Error performing certificate Inventory: " + ex.Message); @@ -177,14 +153,13 @@ private JobResult ProcessJob(CitrixAdcStore store, InventoryJobConfiguration job { Result = Orchestrators.Common.Enums.OrchestratorJobStatusJobResult.Failure, JobHistoryId = jobConfiguration.JobHistoryId, - FailureMessage = "Error while performing certificate Inventory" + FailureMessage = "Error while performing certificate Inventory" + ex.Message }; } try { _logger.LogDebug("Sending results back to command"); - //Sends inventoried certificates back to KF Command submitInventoryUpdate.Invoke(inventory); _logger.LogDebug("Successfully Completed Job"); diff --git a/CitrixAdcOrchestratorJobExtension/Management.cs b/CitrixAdcOrchestratorJobExtension/Management.cs index 247bafb..00fd247 100644 --- a/CitrixAdcOrchestratorJobExtension/Management.cs +++ b/CitrixAdcOrchestratorJobExtension/Management.cs @@ -170,7 +170,7 @@ private JobResult ProcessJob(CitrixAdcStore store, ManagementJobConfiguration jo { //PerformRenewal //1. Get All Keys /config/sslcertkey store.ListKeyPairs() - var keyPairList = store.ListKeyPairs(); + var keyPairList = store.GetCertificates(); _logger.LogTrace($"KeyPairList: {JsonConvert.SerializeObject(keyPairList)}"); @@ -178,9 +178,7 @@ private JobResult ProcessJob(CitrixAdcStore store, ManagementJobConfiguration jo foreach (var kp in keyPairList) { //4. Open the file and check the thumbprint - var x = store.GetX509Certificate( - kp.cert.Substring(kp.cert.LastIndexOf("/", StringComparison.Ordinal) + 1), - out _); + var x = store.GetX509Certificate(kp); //5. If the Thumbprint matches the cert renewed from KF then PerformAdd With Overwrite if (x?.Thumbprint == _thumbprint)