Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 2.1 #28

Merged
merged 17 commits into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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


Loading