Skip to content
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
20 changes: 0 additions & 20 deletions .github/workflows/keyfactor-bootstrap-workflow-v3.yml

This file was deleted.

29 changes: 29 additions & 0 deletions .github/workflows/keyfactor-bootstrap-workflow.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Keyfactor Bootstrap Workflow

on:
workflow_dispatch:
pull_request:
types: [opened, closed, synchronize, edited, reopened]
push:
create:
branches:
- 'release-*.*'

jobs:
call-starter-workflow:
uses: keyfactor/actions/.github/workflows/starter.yml@v4
permissions:
contents: write # Explicitly grant write permission
with:
command_token_url: ${{ vars.COMMAND_TOKEN_URL }}
command_hostname: ${{ vars.COMMAND_HOSTNAME }}
command_base_api_path: ${{ vars.COMMAND_API_PATH }}
secrets:
token: ${{ secrets.V2BUILDTOKEN}}
gpg_key: ${{ secrets.KF_GPG_PRIVATE_KEY }}
gpg_pass: ${{ secrets.KF_GPG_PASSPHRASE }}
scan_token: ${{ secrets.SAST_TOKEN }}
entra_username: ${{ secrets.DOCTOOL_ENTRA_USERNAME }}
entra_password: ${{ secrets.DOCTOOL_ENTRA_PASSWD }}
command_client_id: ${{ secrets.COMMAND_CLIENT_ID }}
command_client_secret: ${{ secrets.COMMAND_CLIENT_SECRET }}
18 changes: 11 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<h1 align="center" style="border-bottom: none">
GlobalSign MSSL Gateway AnyCA Gateway REST Plugin
GlobalSign MSSL AnyCA Gateway REST Plugin
</h1>

<p align="center">
Expand Down Expand Up @@ -38,10 +38,10 @@ The GlobalSign CAPlugin enables the Synchronization, Enrollment, and Revocation

## Compatibility

The GlobalSign MSSL Gateway AnyCA Gateway REST plugin is compatible with the Keyfactor AnyCA Gateway REST 25.2.0 and later.
The GlobalSign MSSL AnyCA Gateway REST plugin is compatible with the Keyfactor AnyCA Gateway REST 25.2.0 and later.

## Support
The GlobalSign MSSL Gateway AnyCA Gateway REST plugin is supported by Keyfactor for Keyfactor customers. If you have a support issue, please open a support ticket with your Keyfactor representative. If you have a support issue, please open a support ticket via the Keyfactor Support Portal at https://support.keyfactor.com.
The GlobalSign MSSL AnyCA Gateway REST plugin is supported by Keyfactor for Keyfactor customers. If you have a support issue, please open a support ticket with your Keyfactor representative. If you have a support issue, please open a support ticket via the Keyfactor Support Portal at https://support.keyfactor.com.

> To report a problem or suggest a new feature, use the **[Issues](../../issues)** tab. If you want to contribute actual bug fixes or proposed enhancements, use the **[Pull requests](../../pulls)** tab.

Expand All @@ -60,7 +60,7 @@ This extension uses the contact information of the GCC Domain point of contact f

1. Install the AnyCA Gateway REST per the [official Keyfactor documentation](https://software.keyfactor.com/Guides/AnyCAGatewayREST/Content/AnyCAGatewayREST/InstallIntroduction.htm).

2. On the server hosting the AnyCA Gateway REST, download and unzip the latest [GlobalSign MSSL Gateway AnyCA Gateway REST plugin](https://github.com/Keyfactor/globalsign-mssl-caplugin/releases/latest) from GitHub.
2. On the server hosting the AnyCA Gateway REST, download and unzip the latest [GlobalSign MSSL AnyCA Gateway REST plugin](https://github.com/Keyfactor/globalsign-mssl-caplugin/releases/latest) from GitHub.

3. Copy the unzipped directory (usually called `net6.0` or `net8.0`) to the Extensions directory:

Expand All @@ -71,11 +71,11 @@ This extension uses the contact information of the GCC Domain point of contact f
Program Files\Keyfactor\AnyCA Gateway\AnyGatewayREST\net8.0\Extensions
```

> The directory containing the GlobalSign MSSL Gateway AnyCA Gateway REST plugin DLLs (`net6.0` or `net8.0`) can be named anything, as long as it is unique within the `Extensions` directory.
> The directory containing the GlobalSign MSSL AnyCA Gateway REST plugin DLLs (`net6.0` or `net8.0`) can be named anything, as long as it is unique within the `Extensions` directory.

4. Restart the AnyCA Gateway REST service.

5. Navigate to the AnyCA Gateway REST portal and verify that the Gateway recognizes the GlobalSign MSSL Gateway plugin by hovering over the ⓘ symbol to the right of the Gateway on the top left of the portal.
5. Navigate to the AnyCA Gateway REST portal and verify that the Gateway recognizes the GlobalSign MSSL plugin by hovering over the ⓘ symbol to the right of the Gateway on the top left of the portal.

## Configuration

Expand Down Expand Up @@ -103,8 +103,10 @@ This extension uses the contact information of the GCC Domain point of contact f
* **RetryCount** - This is the number of times the AnyGateway will attempt to pickup an new certificate before reporting an error. Default is 5.
* **SyncIntervalDays** - OPTIONAL: Required if SyncStartDate is used. Specifies how to page the certificate sync. Should be a value such that no interval of that length contains > 500 certificate enrollments.
* **SyncStartDate** - If provided, full syncs will start at the specified date.
* **SyncProducts** - OPTIONAL: If provided as a comma-separated list of product IDs, will limit the certificate sync to only certificates of those products. If blank or not provided, will sync all certs.
* **Enabled** - Flag to Enable or Disable gateway functionality. Disabling is primarily used to allow creation of the CA prior to configuration information being available.

2. Define [Certificate Profiles](https://software.keyfactor.com/Guides/AnyCAGatewayREST/Content/AnyCAGatewayREST/AddCP-Gateway.htm) and [Certificate Templates](https://software.keyfactor.com/Guides/AnyCAGatewayREST/Content/AnyCAGatewayREST/AddCA-Gateway.htm) for the Certificate Authority as required. One Certificate Profile must be defined per Certificate Template. It's recommended that each Certificate Profile be named after the Product ID. The GlobalSign MSSL Gateway plugin supports the following product IDs:
2. Define [Certificate Profiles](https://software.keyfactor.com/Guides/AnyCAGatewayREST/Content/AnyCAGatewayREST/AddCP-Gateway.htm) and [Certificate Templates](https://software.keyfactor.com/Guides/AnyCAGatewayREST/Content/AnyCAGatewayREST/AddCA-Gateway.htm) for the Certificate Authority as required. One Certificate Profile must be defined per Certificate Template. It's recommended that each Certificate Profile be named after the Product ID. The GlobalSign MSSL plugin supports the following product IDs:

* **PEV_SHA2**
* **PEV**
Expand All @@ -123,6 +125,8 @@ This extension uses the contact information of the GCC Domain point of contact f
* **CertificateValidityInYears** - Number of years the certificate will be valid for
* **SlotSize** - Maximum number of SANs that a certificate may have - valid values are [FIVE, TEN, FIFTEEN, TWENTY, THIRTY, FOURTY, FIFTY, ONE_HUNDRED]
* **RootCAType** - The certificate's root CA - Depending on certificate expiration date, SHA_1 not be allowed. Will default to SHA_2 if expiration date exceeds sha1 allowed date. Options are GlobalSign R certs.
* **MSSLProfileId** - OPTIONAL: If specified, enrollments will use that profile ID for domain lookups. If not provided, domain lookup will be done based on the Common Name or first DNS SAN. Useful if your GlobalSign account has multiple domain objects with the same domain string, or subdomains (e.g. sub.test.com vs test.com).
* **ContactName** - The name of the contact to use for enrollments. Can be specified here or via an Enrollment Field in Command. Enrollment Fields will override any value supplied here.


## Valid GlobalSign SAN Usage
Expand Down
27 changes: 26 additions & 1 deletion globalsign-mssl-caplugin/Api/GlobalSignEnrollRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,32 @@ public BmV2PvOrderRequest Request
continue;
}

var entry = new SANEntry();
string trimCN = CommonName, trimItem = item;

if (CommonName.StartsWith("*."))
{
trimCN = CommonName.Substring(2).ToLower();
trimItem = item.ToLower();
List<string> equivs = new List<string> { $"*.{trimCN}", $"www.{trimCN}", $"{trimCN}" };
if (equivs.Contains(trimItem))
{
Logger.LogInformation($"SAN Entry {item} is equivalent to CN ignoring wildcards or www prefix, removing from request");
continue;
}
}
else if (CommonName.StartsWith("www."))
{
trimCN = CommonName.Substring(4).ToLower();
trimItem = item.ToLower();
List<string> equivs = new List<string> { $"www.{trimCN}", $"{trimCN}" };
if (equivs.Contains(trimItem))
{
Logger.LogInformation($"SAN Entry {item} is equivalent to CN ignoring wildcards or www prefix, removing from request");
continue;
}
}

var entry = new SANEntry();
entry.SubjectAltName = item;
var sb = new StringBuilder();
sb.Append("Adding SAN entry of type ");
Expand Down
25 changes: 24 additions & 1 deletion globalsign-mssl-caplugin/Api/GlobalSignRenewRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,31 @@ public GlobalSignRenewRequest(GlobalSignCAConfig config, bool privateDomain, boo
Logger.LogInformation($"SAN Entry {item} matches CN, removing from request");
continue;
}
string trimCN = CommonName, trimItem = item;

var entry = new SANEntry();
if (CommonName.StartsWith("*."))
{
trimCN = CommonName.Substring(2).ToLower();
trimItem = item.ToLower();
List<string> equivs = new List<string> { $"*.{trimCN}", $"www.{trimCN}", $"{trimCN}" };
if (equivs.Contains(trimItem))
{
Logger.LogInformation($"SAN Entry {item} is equivalent to CN ignoring wildcards or www prefix, removing from request");
continue;
}
}
else if (CommonName.StartsWith("www."))
{
trimCN = CommonName.Substring(4).ToLower();
trimItem = item.ToLower();
List<string> equivs = new List<string> { $"www.{trimCN}", $"{trimCN}" };
if (equivs.Contains(trimItem))
{
Logger.LogInformation($"SAN Entry {item} is equivalent to CN ignoring wildcards or www prefix, removing from request");
continue;
}
}
var entry = new SANEntry();
entry.SubjectAltName = item;
var sb = new StringBuilder();
sb.Append("Adding SAN entry of type ");
Expand Down
29 changes: 19 additions & 10 deletions globalsign-mssl-caplugin/Client/GlobalSignApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,18 @@
public ManagedSSLV2 OrderService;
public GASV1 QueryService;

public GlobalSignApiClient(GlobalSignCAConfig config, ILogger logger)

Check warning on line 24 in globalsign-mssl-caplugin/Client/GlobalSignApiClient.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-dotnet-build-and-release-workflow / dotnet-build-and-release

Non-nullable field 'QueryService' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 24 in globalsign-mssl-caplugin/Client/GlobalSignApiClient.cs

View workflow job for this annotation

GitHub Actions / call-starter-workflow / call-dotnet-build-and-release-workflow / dotnet-build-and-release

Non-nullable field 'OrderService' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.
{
Logger = logger;
Config = config;
// Logger = LogHandler.GetClassLogger(this.GetType());
var enabled =config.Enabled;
if (!enabled)
{
Logger.LogWarning($"The CA is currently in the Disabled state. It must be Enabled to perform operations. Skipping config validation and MSSL Client creation...");
Logger.MethodExit();
return;
}
QueryService = new GASV1Client
{
Endpoint = { Address = new EndpointAddress(config.GetUrl(GlobalSignServiceType.QUERY)), Name = "QUERY" }
Expand All @@ -47,10 +54,8 @@
var results = new List<OrderDetail>();
if (fullSync)
{
// If startDate is before year 2000, treat it as “since the dawn of time”
var from = startDate > new DateTime(2000, 1, 1)
? startDate
: DateTime.MinValue;

var from = startDate;
var finalStop = DateTime.UtcNow;

// first window
Expand All @@ -72,8 +77,12 @@
}
else
{
// incremental sync since lastSync
// incremental sync since lastSync, unless lastSync is earlier than startDate, then use that
var from = lastSync;
if (from < startDate)
{
from = startDate;
}
var to = DateTime.UtcNow;

results.AddRange(
Expand Down Expand Up @@ -272,19 +281,19 @@
Logger.MethodEntry();
var rawRequest = enrollRequest.Request;
Logger.LogTrace("Request details:");
Logger.LogTrace($"Profile ID: {enrollRequest.MsslProfileId}");
Logger.LogTrace($"Domain ID: {enrollRequest.MsslDomainId}");
Logger.LogTrace($"Profile ID: {rawRequest.MSSLProfileID}");
Logger.LogTrace($"Domain ID: {rawRequest.MSSLDomainID}");
Logger.LogTrace(
$"Contact Info: {enrollRequest.FirstName}, {enrollRequest.LastName}, {enrollRequest.Email}, {enrollRequest.Phone}");
Logger.LogTrace($"SAN Count: {enrollRequest.SANs.Count()}");
$"Contact Info: {rawRequest.ContactInfo.FirstName}, {rawRequest.ContactInfo.LastName}, {rawRequest.ContactInfo.Email}, {rawRequest.ContactInfo.Phone}");
Logger.LogTrace($"SAN Count: {rawRequest.SANEntries.Count()}");
if (rawRequest.SANEntries.Count() > 0)
Logger.LogTrace($"SANs: {string.Join(",", rawRequest.SANEntries.Select(s => s.SubjectAltName))}");
Logger.LogTrace($"Product Code: {rawRequest.OrderRequestParameter.ProductCode}");
Logger.LogTrace($"Order Kind: {rawRequest.OrderRequestParameter.OrderKind}");
if (!string.IsNullOrEmpty(rawRequest.OrderRequestParameter.BaseOption))
Logger.LogTrace($"Order Base Option: {rawRequest.OrderRequestParameter.BaseOption}");

var requestwrapper = new PVOrder(enrollRequest.Request);
var requestwrapper = new PVOrder(rawRequest);
var responsewrapper = await OrderService.PVOrderAsync(requestwrapper);
;
var response = responsewrapper.Response;
Expand Down
4 changes: 4 additions & 0 deletions globalsign-mssl-caplugin/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,15 @@ internal class Constants
public static string PICKUPDELAY = "DelayTime";
public static string SYNCSTARTDATE = "SyncStartDate";
public static string SYNCINTERNVALDAYS = "SyncIntervalDays";
public static string SYNCPRODUCTS = "SyncProducts";
public static string Enabled = "Enabled";
}

public static class EnrollmentConfigConstants
{
public const string RootCAType = "RootCAType";
public const string SlotSize = "SlotSize";
public const string CertificateValidityInYears = "CertificateValidityInYears";
public const string MSSLProfileId = "MSSLProfileId";
public const string ContactName = "ContactName";
}
2 changes: 2 additions & 0 deletions globalsign-mssl-caplugin/GlobalSignCAConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ public class GlobalSignCAConfig

public string SyncStartDate { get; set; } = "";
public int SyncIntervalDays { get; set; } = 0;
public string SyncProducts { get; set; } = "";

public bool Enabled { get; set; } = true;

public string GetUrl(GlobalSignServiceType queryType)
{
Expand Down
Loading
Loading