|
24 | 24 | using System.Collections.Concurrent;
|
25 | 25 | using System.Drawing.Printing;
|
26 | 26 | using System.Diagnostics.CodeAnalysis;
|
| 27 | +using static Keyfactor.Orchestrators.Common.OrchestratorConstants; |
| 28 | +using static Org.BouncyCastle.Math.EC.ECCurve; |
27 | 29 |
|
28 | 30 | namespace Keyfactor.Extensions.Orchestrator.F5Orchestrator
|
29 | 31 | {
|
@@ -91,7 +93,9 @@ public void AddEntry(string partition, string name, string b64Certificate, strin
|
91 | 93 | {
|
92 | 94 | LogHandlerCommon.MethodEntry(logger, CertificateStore, "AddEntry");
|
93 | 95 | LogHandlerCommon.Trace(logger, CertificateStore, $"Processing certificate for partition '{partition}' and name '{name}'");
|
| 96 | + LogHandlerCommon.Trace(logger, CertificateStore, $"*** CERT CONTENTS: *** {b64Certificate}"); |
94 | 97 | byte[] entryContents = Convert.FromBase64String(b64Certificate);
|
| 98 | + LogHandlerCommon.Trace(logger, CertificateStore, $"*** AFTER CERT CONTENTS: ***"); |
95 | 99 | string password = PFXPassword;
|
96 | 100 | CertificateConverter converter = CertificateConverterFactory.FromDER(entryContents, password);
|
97 | 101 | X509Certificate2 certificate = converter.ToX509Certificate2(password);
|
@@ -350,6 +354,35 @@ private X509Certificate2Collection GetCertificateEntry(string path)
|
350 | 354 | return c.ToX509Certificate2Collection();
|
351 | 355 | }
|
352 | 356 |
|
| 357 | + public List<F5SSLProfile> GetSSLProfiles(int pageSize) |
| 358 | + { |
| 359 | + LogHandlerCommon.MethodEntry(logger, CertificateStore, "GetSSLProfiles"); |
| 360 | + string partition = CertificateStore.StorePath; |
| 361 | + string query = $"/mgmt/tm/ltm/profile/client-ssl?$top={pageSize}&$skip=0"; |
| 362 | + F5PagedSSLProfiles pagedProfiles = REST.Get<F5PagedSSLProfiles>(query); |
| 363 | + List<F5SSLProfile> profiles = new List<F5SSLProfile>(); |
| 364 | + |
| 365 | + if (pagedProfiles.totalItems == 0 || pagedProfiles.items?.Length == 0) |
| 366 | + { |
| 367 | + return profiles; |
| 368 | + } |
| 369 | + |
| 370 | + for (int i = pagedProfiles.pageIndex; i <= pagedProfiles.totalPages; i++) |
| 371 | + { |
| 372 | + profiles.AddRange(pagedProfiles.items); |
| 373 | + |
| 374 | + // The current paged profile will contain a link to the next set, unless the end has been reached |
| 375 | + if (string.IsNullOrEmpty(pagedProfiles.nextLink)) { break; } |
| 376 | + |
| 377 | + // Get the next page of profiles |
| 378 | + query = pagedProfiles.nextLink.Replace("https://localhost", ""); |
| 379 | + pagedProfiles = REST.Get<F5PagedSSLProfiles>(query); |
| 380 | + } |
| 381 | + |
| 382 | + LogHandlerCommon.MethodExit(logger, CertificateStore, "GetCertificateEntries"); |
| 383 | + return profiles; |
| 384 | + } |
| 385 | + |
353 | 386 | private void SetItemStatus(CurrentInventoryItem agentInventoryItem)
|
354 | 387 | {
|
355 | 388 | LogHandlerCommon.MethodEntry(logger, CertificateStore, "SetItemStatus");
|
@@ -609,67 +642,79 @@ private List<X509Certificate2> ReorderPEMLIst(List<X509Certificate2> certList)
|
609 | 642 | // WebServer
|
610 | 643 | #endregion
|
611 | 644 |
|
612 |
| - #region SSL Profiles |
| 645 | + #region SSL Certificates |
613 | 646 |
|
614 |
| - public List<CurrentInventoryItem> GetSSLProfiles(int pageSize) |
| 647 | + public List<CurrentInventoryItem> GetCertificateEntries(int pageSize) |
615 | 648 | {
|
616 |
| - LogHandlerCommon.MethodEntry(logger, CertificateStore, "GetSSLProfiles"); |
| 649 | + LogHandlerCommon.MethodEntry(logger, CertificateStore, "GetCertificateEntries"); |
617 | 650 | string partition = CertificateStore.StorePath;
|
618 | 651 | string query = $"/mgmt/tm/sys/file/ssl-cert?$filter=partition+eq+{partition}&$select=name,keyType,isBundle&$top={pageSize}&$skip=0";
|
619 |
| - F5PagedSSLProfiles pagedProfiles = REST.Get<F5PagedSSLProfiles>(query); |
620 |
| - List<F5SSLProfile> profiles = new List<F5SSLProfile>(); |
| 652 | + F5PagedSSLCertificates pagedCertificates = REST.Get<F5PagedSSLCertificates>(query); |
| 653 | + List<F5SSLCertificate> certificates = new List<F5SSLCertificate>(); |
621 | 654 | List<CurrentInventoryItem> inventory = new List<CurrentInventoryItem>();
|
622 | 655 |
|
623 |
| - if (pagedProfiles.totalItems == 0 || pagedProfiles.items?.Length == 0) |
| 656 | + LogHandlerCommon.Debug(logger, CertificateStore, $"Getting SSL Profiles from '{CertificateStore.StorePath}'"); |
| 657 | + List<F5SSLProfile> sslProfiles = GetSSLProfiles(pageSize); |
| 658 | + |
| 659 | + if (pagedCertificates.totalItems == 0 || pagedCertificates.items?.Length == 0) |
624 | 660 | {
|
625 |
| - LogHandlerCommon.Trace(logger, CertificateStore, $"No SSL profiles found in partition '{partition}'"); |
626 |
| - LogHandlerCommon.MethodExit(logger, CertificateStore, "GetSSLProfiles"); |
| 661 | + LogHandlerCommon.Trace(logger, CertificateStore, $"No SSL certificates found in partition '{partition}'"); |
| 662 | + LogHandlerCommon.MethodExit(logger, CertificateStore, "GetCertificateEntries"); |
627 | 663 | return inventory;
|
628 | 664 | }
|
629 | 665 | else
|
630 | 666 | {
|
631 |
| - LogHandlerCommon.Trace(logger, CertificateStore, $"Compiling {pagedProfiles.totalPages} pages containing {pagedProfiles.totalItems} total inventory entries"); |
| 667 | + LogHandlerCommon.Trace(logger, CertificateStore, $"Compiling {pagedCertificates.totalPages} pages containing {pagedCertificates.totalItems} total inventory entries"); |
632 | 668 | }
|
633 | 669 |
|
634 |
| - // Collected all of the profile entry names |
635 |
| - for (int i = pagedProfiles.pageIndex; i <= pagedProfiles.totalPages; i++) |
| 670 | + // Collected all of the certificate entry names |
| 671 | + for (int i = pagedCertificates.pageIndex; i <= pagedCertificates.totalPages; i++) |
636 | 672 | {
|
637 |
| - profiles.AddRange(pagedProfiles.items); |
| 673 | + certificates.AddRange(pagedCertificates.items); |
638 | 674 |
|
639 |
| - // The current paged profile will contain a link to the next set, unless the end has been reached |
640 |
| - if (string.IsNullOrEmpty(pagedProfiles.nextLink)) { break; } |
| 675 | + // The current paged certificate list will contain a link to the next set, unless the end has been reached |
| 676 | + if (string.IsNullOrEmpty(pagedCertificates.nextLink)) { break; } |
641 | 677 |
|
642 |
| - // Get the next page of profiles |
643 |
| - query = pagedProfiles.nextLink.Replace("https://localhost", ""); |
644 |
| - pagedProfiles = REST.Get<F5PagedSSLProfiles>(query); |
| 678 | + // Get the next page of certificates |
| 679 | + query = pagedCertificates.nextLink.Replace("https://localhost", ""); |
| 680 | + pagedCertificates = REST.Get<F5PagedSSLCertificates>(query); |
645 | 681 | }
|
646 | 682 |
|
647 | 683 | // Compile the entries into inventory items
|
648 |
| - for (int i = 0; i < profiles.Count; i++) |
| 684 | + for (int i = 0; i < certificates.Count; i++) |
649 | 685 | {
|
650 | 686 | try
|
651 | 687 | {
|
652 |
| - LogHandlerCommon.Trace(logger, CertificateStore, $"Processing alias {profiles[i].name}"); |
| 688 | + LogHandlerCommon.Trace(logger, CertificateStore, $"Processing alias {certificates[i].name}"); |
653 | 689 | // Exclude 'ca-bundle.crt' as that can only be managed by F5
|
654 |
| - if (profiles[i].name.Equals("ca-bundle.crt", StringComparison.OrdinalIgnoreCase) |
655 |
| - || profiles[i].name.Equals("f5-ca-bundle.crt", StringComparison.OrdinalIgnoreCase)) |
| 690 | + if (certificates[i].name.Equals("ca-bundle.crt", StringComparison.OrdinalIgnoreCase) |
| 691 | + || certificates[i].name.Equals("f5-ca-bundle.crt", StringComparison.OrdinalIgnoreCase)) |
656 | 692 | {
|
657 |
| - LogHandlerCommon.Trace(logger, CertificateStore, $"Skipping '{profiles[i].name}' because it is managed by F5"); |
| 693 | + LogHandlerCommon.Trace(logger, CertificateStore, $"Skipping '{certificates[i].name}' because it is managed by F5"); |
658 | 694 | continue;
|
659 | 695 | }
|
660 |
| - inventory.Add(GetInventoryItem(partition, profiles[i].name, true)); |
| 696 | + CurrentInventoryItem inventoryItem = GetInventoryItem(partition, certificates[i].name, true); |
| 697 | + Dictionary<string, object> parameters = new Dictionary<string, object>(); |
| 698 | + |
| 699 | + string certName = $"/{partition}/{inventoryItem.Alias}"; |
| 700 | + string sslProfileNames = string.Join(",", sslProfiles.Where(p => p.cert == certName).Select(p => p.name)); |
| 701 | + if (!string.IsNullOrEmpty(sslProfileNames)) |
| 702 | + parameters.Add("SSLProfiles", sslProfileNames); |
| 703 | + inventoryItem.Parameters = parameters; |
| 704 | + |
| 705 | + inventory.Add(inventoryItem); |
661 | 706 | }
|
662 | 707 | catch (Exception ex)
|
663 | 708 | {
|
664 |
| - LogHandlerCommon.Error(logger, CertificateStore, ExceptionHandler.FlattenExceptionMessages(ex, $"Unable to process inventory item {profiles[i].name}.")); |
| 709 | + LogHandlerCommon.Error(logger, CertificateStore, ExceptionHandler.FlattenExceptionMessages(ex, $"Unable to process inventory item {certificates[i].name}.")); |
665 | 710 | }
|
666 | 711 | }
|
667 | 712 |
|
668 |
| - LogHandlerCommon.MethodExit(logger, CertificateStore, "GetSSLProfiles"); |
| 713 | + LogHandlerCommon.MethodExit(logger, CertificateStore, "GetCertificateEntries"); |
669 | 714 | return inventory;
|
670 | 715 | }
|
671 | 716 |
|
672 |
| - // SSL Profiles |
| 717 | + // SSL Certificates |
673 | 718 | #endregion
|
674 | 719 |
|
675 | 720 | #region Auth & Version
|
|
0 commit comments