Skip to content

Commit

Permalink
Merge pull request #28 from Keyfactor/release-2.1
Browse files Browse the repository at this point in the history
Release 2.1
  • Loading branch information
fiddlermikey authored Apr 30, 2024
2 parents 1f8e677 + c56f15f commit 1349696
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 36 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
2.1.1
* Fix issue identifying whether inventoried certificate contains a private key.
* Renewing Unbound Certificates Causes The Job To Fail

2.1.0
* Added new Custom Field, Link To Issuer, to identify if Managment-Add jobs should attempt to link an added certificate to its issuing certificate if it resides in Netscaler.

2.0.1
* Fixed Issue with Inventory when VServer Cannot be retreived by Citrix API

Expand Down
27 changes: 19 additions & 8 deletions CitrixAdcOrchestratorJobExtension/CitrixAdcStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,7 @@ public X509Certificate2 GetX509Certificate(string fileLocation, out bool hasKey)
{
Logger.LogDebug("Entering GetX509Certificate(string fileLocation, out bool hasKey)");
systemfile f;
string[] privateKeyDelims = new string[3] { "-----BEGIN RSA PRIVATE KEY-----", "-----BEGIN PRIVATE KEY-----", "-----BEGIN ENCRYPTED PRIVATE KEY-----" };

string certString = null;
string keyString = null;
Expand Down Expand Up @@ -701,18 +702,24 @@ public X509Certificate2 GetX509Certificate(string fileLocation, out bool hasKey)
var fileString = Encoding.Default.GetString(b);

// Check if private key is included with certificate
var containsKey = fileString.IndexOf("-----BEGIN RSA PRIVATE KEY-----", StringComparison.Ordinal) >= 0;
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;

Logger.LogTrace($"containsKey: {containsKey} containsCert: {containsCert}");
Logger.LogTrace($"containsKey: {privateKeyIdx > -1} containsCert: {containsCert}");

if (containsCert && containsKey)
if (containsCert && privateKeyIdx > -1)
{
Logger.LogTrace($"File contains certificate and key: {fileLocation}");

var keyStart = fileString.IndexOf("-----BEGIN RSA PRIVATE KEY-----", StringComparison.Ordinal);
var keyEnd = fileString.IndexOf("-----END RSA PRIVATE KEY-----", StringComparison.Ordinal) +
"-----END RSA PRIVATE KEY-----".Length;
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);
Expand All @@ -725,7 +732,11 @@ public X509Certificate2 GetX509Certificate(string fileLocation, out bool hasKey)
// check .key file
try
{
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileLocation);
var fileNameWithoutExtension = fileLocation;
if (fileLocation.EndsWith(".crt",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));
}
Expand Down Expand Up @@ -754,7 +765,7 @@ public X509Certificate2 GetX509Certificate(string fileLocation, out bool hasKey)
return null;
}

hasKey = EvaluatePrivateKey(x, keyString);
hasKey = !string.IsNullOrEmpty(keyString);
}
catch (Exception e)
{
Expand Down
59 changes: 33 additions & 26 deletions CitrixAdcOrchestratorJobExtension/Management.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ private void AddBindCert(CitrixAdcStore store, ManagementJobCertificate cert, st

_logger.LogDebug("Updating cert bindings");
//update cert bindings
store.UpdateBindings(keyPairName, virtualServerName, sniCert);
if (virtualServerName != null)
store.UpdateBindings(keyPairName, virtualServerName, sniCert);

if (linkToIssuer)
{
Expand Down Expand Up @@ -176,41 +177,47 @@ private JobResult ProcessJob(CitrixAdcStore store, ManagementJobConfiguration jo
//2. For Each check the binding /config/sslcertkey_binding store.GetBinding(strKey)
foreach (var kp in keyPairList)
{
var binding = store.GetBinding(kp.certkey);
_logger.LogTrace($"binding: {JsonConvert.SerializeObject(binding)}");
if (binding != null)
//4. Open the file and check the thumbprint
var x = store.GetX509Certificate(
kp.cert.Substring(kp.cert.LastIndexOf("/", StringComparison.Ordinal) + 1),
out _);

//5. If the Thumbprint matches the cert renewed from KF then PerformAdd With Overwrite
if (x?.Thumbprint == _thumbprint)
{
//4. Open the file and check the thumbprint
var x = store.GetX509Certificate(
kp.cert.Substring(kp.cert.LastIndexOf("/", StringComparison.Ordinal) + 1),
out _);
//5. If the Thumbprint matches the cert renewed from KF then PerformAdd With Overwrite
if (x?.Thumbprint == _thumbprint)
_logger.LogTrace($"Thumbprint Match: {_thumbprint}");
var binding = store.GetBinding(kp.certkey);
_logger.LogTrace($"binding: {JsonConvert.SerializeObject(binding)}");
if (binding != null)
{
_logger.LogTrace($"Thumbprint Match: {_thumbprint}");
if (binding.sslcertkey_sslvserver_binding == null)
if (binding?.sslcertkey_sslvserver_binding != null)
{
_logger.LogTrace(
$"Starting PerformAdd Binding kp.certkey: {kp.certkey}");
PerformAdd(store, jobConfiguration.JobCertificate, kp.certkey,
virtualServerName, true, sniCert, linkToIssuer);
_logger.LogTrace(
$"Finished PerformAdd kp.certkey: {kp.certkey}");
}
else
{
foreach (var sBinding in binding.sslcertkey_sslvserver_binding)
foreach (var sBinding in binding?.sslcertkey_sslvserver_binding)
{
_logger.LogTrace(
$"Starting PerformAdd Binding Name: {sBinding.servername} kp.certkey: {kp.certkey}");
PerformAdd(store, jobConfiguration.JobCertificate, kp.certkey,
sBinding.servername, true, sniCert, linkToIssuer);
$"Starting PerformAdd Binding Name: {sBinding?.servername} kp.certkey: {kp?.certkey}");
PerformAdd(store, jobConfiguration.JobCertificate, kp?.certkey,
sBinding?.servername, true, sniCert, linkToIssuer);
_logger.LogTrace(
$"Finished PerformAdd Binding Name: {sBinding.servername} kp.certkey: {kp.certkey}");
$"Finished PerformAdd Binding Name: {sBinding?.servername} kp.certkey: {kp?.certkey}");
}
}
else
{
_logger.LogTrace($"Renewing cert with no binding Information");
PerformAdd(store, jobConfiguration.JobCertificate, kp?.certkey, null, true, null, linkToIssuer);
_logger.LogTrace($"Finished Renewing cert with no binding Information");
}
}
else
{
_logger.LogTrace($"Renewing cert with no binding Information");
PerformAdd(store, jobConfiguration.JobCertificate, kp?.certkey,null, true, null,linkToIssuer);
_logger.LogTrace($"Finished Renewing cert with no binding Information");
}

}

}
}
}
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ The Keyfactor Universal Orchestrator may be installed on either Windows or Linux
|Supports Management Remove|✓ |✓ |
|Supports Create Store| | |
|Supports Discovery| | |
|Supports Renrollment| | |
|Supports Reenrollment| | |
|Supports Inventory|✓ |✓ |


Expand Down Expand Up @@ -248,3 +248,6 @@ Case Number|Case Name|Enrollment Params|Expected Results|Passed|Screenshot

</details>

When creating cert store type manually, that store property names and entry parameter names are case sensitive


0 comments on commit 1349696

Please sign in to comment.