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
3 changes: 1 addition & 2 deletions .github/workflows/keyfactor-bootstrap-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ on:

jobs:
call-starter-workflow:
uses: keyfactor/actions/.github/workflows/starter.yml@v3
uses: keyfactor/actions/.github/workflows/starter.yml@v5
secrets:
token: ${{ secrets.V2BUILDTOKEN}}
APPROVE_README_PUSH: ${{ secrets.APPROVE_README_PUSH}}
gpg_key: ${{ secrets.KF_GPG_PRIVATE_KEY }}
gpg_pass: ${{ secrets.KF_GPG_PASSPHRASE }}
scan_token: ${{ secrets.SAST_TOKEN }}
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,9 @@ Change incremental sync to use GetModifiedOrders API call

1.1.2
Add 30 day window from expiration for doing renewals instead of reissues

1.1.3
Return EXTERNALVALIDATION status for all pending requests.

2.0.0
Add support for automated domain validation via DNS gateway plugins.
60 changes: 32 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<!-- TOC -->
<a href="#support">
<b>Support</b>
</a>
</a>
·
<a href="#requirements">
<b>Requirements</b>
Expand All @@ -33,15 +33,14 @@
</a>
</p>


The GlobalSign CAPlugin enables the Synchronization, Enrollment, and Revocation of TLS Certificates from the GlobalSign Certificate Center.

## Compatibility

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

## Support
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.
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 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 @@ -62,16 +61,16 @@ This extension uses the contact information of the GCC Domain point of contact f

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:
3. Copy the unzipped directory (usually called `net8.0` or `net10.0`) to the Extensions directory:


```shell
Depending on your AnyCA Gateway REST version, copy the unzipped directory to one of the following locations:
Program Files\Keyfactor\AnyCA Gateway\AnyGatewayREST\net6.0\Extensions
Program Files\Keyfactor\AnyCA Gateway\AnyGatewayREST\net8.0\Extensions
Program Files\Keyfactor\AnyCA Gateway\AnyGatewayREST\net10.0\Extensions
```

> 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.
> The directory containing the GlobalSign MSSL AnyCA Gateway REST plugin DLLs (`net8.0` or `net10.0`) can be named anything, as long as it is unique within the `Extensions` directory.

4. Restart the AnyCA Gateway REST service.

Expand All @@ -91,20 +90,20 @@ This extension uses the contact information of the GCC Domain point of contact f

Populate using the configuration fields collected in the [requirements](#requirements) section.

* **GlobalSignUsername** - GlobalSign MSSL API Username
* **GlobalSignPassword** - GlobalSign MSSL API Password
* **DateFormatString** - Date format string. Default is yyyy-MM-ddTHH:mm:ss.fffZ
* **OrderAPIProdURL** - MSSL Order Prod API URL. Default is https://system.globalsign.com/kb/ws/v2/ManagedSSLService
* **OrderAPITestURL** - MSSL Order Test API URL. Default is https://test-gcc.globalsign.com/kb/ws/v2/ManagedSSLService
* **QueryAPIProdURL** - MSSL Query Prod API URL. Default is https://system.globalsign.com/kb/ws/v1/GASService
* **QueryAPITestURL** - MSSL Query Test API URL. Default is https://test-gcc.globalsign.com/kb/ws/v1/GASService
* **TestAPI** - Enable the use of the test GlobalSign API endpoints. Default is false.
* **DelayTime** - This is the number of seconds between retries when attempting to download a certificate. Default is 150.
* **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.
* **GlobalSignUsername** - GlobalSign MSSL API Username
* **GlobalSignPassword** - GlobalSign MSSL API Password
* **DateFormatString** - Date format string. Default is yyyy-MM-ddTHH:mm:ss.fffZ
* **OrderAPIProdURL** - MSSL Order Prod API URL. Default is https://system.globalsign.com/kb/ws/v2/ManagedSSLService
* **OrderAPITestURL** - MSSL Order Test API URL. Default is https://test-gcc.globalsign.com/kb/ws/v2/ManagedSSLService
* **QueryAPIProdURL** - MSSL Query Prod API URL. Default is https://system.globalsign.com/kb/ws/v1/GASService
* **QueryAPITestURL** - MSSL Query Test API URL. Default is https://test-gcc.globalsign.com/kb/ws/v1/GASService
* **TestAPI** - Enable the use of the test GlobalSign API endpoints. Default is false.
* **DelayTime** - This is the number of seconds between retries when attempting to download a certificate. Default is 150.
* **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 plugin supports the following product IDs:

Expand All @@ -122,17 +121,23 @@ This extension uses the contact information of the GCC Domain point of contact f

4. In Keyfactor Command (v12.3+), for each imported Certificate Template, follow the [official documentation](https://software.keyfactor.com/Core-OnPrem/Current/Content/ReferenceGuide/Configuring%20Template%20Options.htm) to define enrollment fields for each of the following parameters:

* **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.

* **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
GlobalSign supports specific combinations of SAN types with certain GlobalSign products. For example, a Private IP can only be used as a SAN with a `PV_INTRA` Certificate.
Please refer to the GlobalSign documentation for more information on SAN usage: [GlobalSign MSSL API User Guide (Section 2.2.5)](https://www.globalsign.com/en/repository/globalsign-mssl-api-user-guide.pdf)

### Automated DNS Domain Validation
This plugin integrates with the AnyCA Gateway **DNS provider plugin framework** (`KeyfactorAnyGateway.IAnyCAPlugin` 3.3.0+). DNS provider plugins (Azure DNS, AWS Route53, Cloudflare, Google Cloud DNS, etc.) are deployed and configured **separately** on the gateway; this CA plugin does not bundle any DNS provider SDKs. The gateway injects an `IDomainValidatorFactory` that resolves the correct provider for each domain at enrollment time.

GlobalSign supports **TXT** records for DNS validation.

`DnsValidationEnabled` determines whether to use the automated validation. Make sure you have the necessary DNS plugins installed and configured before enabling.

## Enrollment

### Required Enrollment Fields
Expand All @@ -150,11 +155,10 @@ The following fields are available for use in the enrollment of `PV_INTRA` Certi
- **RequesterTel**: Set Data Type to 'string' when creating the field. The contact telephone number for the enrollment. Required by the GlobalSign API.
- **InternalIP**: Set Data Type to 'string' when creating the field. Set to `true` if an IP SAN attached during a `PV_INTRA` certificate enrollment is a private IP address (e.g., `10.x.x.x`, `192.168.x.x`, etc.).


## License

Apache License 2.0, see [LICENSE](LICENSE).

## Related Integrations

See all [Keyfactor Any CA Gateways (REST)](https://github.com/orgs/Keyfactor/repositories?q=anycagateway).
See all [Keyfactor Any CA Gateways (REST)](https://github.com/orgs/Keyfactor/repositories?q=anycagateway).
6 changes: 6 additions & 0 deletions docsource/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ Each additional Root will require a separate CA setup.
GlobalSign supports specific combinations of SAN types with certain GlobalSign products. For example, a Private IP can only be used as a SAN with a `PV_INTRA` Certificate.
Please refer to the GlobalSign documentation for more information on SAN usage: [GlobalSign MSSL API User Guide (Section 2.2.5)](https://www.globalsign.com/en/repository/globalsign-mssl-api-user-guide.pdf)

### Automated DNS Domain Validation
This plugin integrates with the AnyCA Gateway **DNS provider plugin framework** (`KeyfactorAnyGateway.IAnyCAPlugin` 3.3.0+). DNS provider plugins (Azure DNS, AWS Route53, Cloudflare, Google Cloud DNS, etc.) are deployed and configured **separately** on the gateway; this CA plugin does not bundle any DNS provider SDKs. The gateway injects an `IDomainValidatorFactory` that resolves the correct provider for each domain at enrollment time.

GlobalSign supports **TXT** records for DNS validation.

`DnsValidationEnabled` determines whether to use the automated validation. Make sure you have the necessary DNS plugins installed and configured before enabling.

## Enrollment

Expand Down
7 changes: 4 additions & 3 deletions globalsign-mssl-caplugin.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.11.35222.181
# Visual Studio Version 18
VisualStudioVersion = 18.9.12105.275 stable
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GlobalSignCAPlugin", "globalsign-mssl-caplugin\GlobalSignCAPlugin.csproj", "{E3B20C7A-1B3C-4FAE-A1C9-EA4CEC400D70}"
EndProject
Expand All @@ -21,7 +21,8 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E3B20C7A-1B3C-4FAE-A1C9-EA4CEC400D70}.Debug|Any CPU.ActiveCfg = DebugAndPush|Any CPU
{E3B20C7A-1B3C-4FAE-A1C9-EA4CEC400D70}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E3B20C7A-1B3C-4FAE-A1C9-EA4CEC400D70}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E3B20C7A-1B3C-4FAE-A1C9-EA4CEC400D70}.DebugAndPush|Any CPU.ActiveCfg = DebugAndPush|Any CPU
{E3B20C7A-1B3C-4FAE-A1C9-EA4CEC400D70}.DebugAndPush|Any CPU.Build.0 = DebugAndPush|Any CPU
{E3B20C7A-1B3C-4FAE-A1C9-EA4CEC400D70}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down
41 changes: 41 additions & 0 deletions globalsign-mssl-caplugin/Api/GlobalSignRenewDomainRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright 2021 Keyfactor
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
// and limitations under the License.

using Order;

namespace Keyfactor.Extensions.CAPlugin.GlobalSign.Api;

public class GlobalSignRenewDomainRequest
{
private readonly GlobalSignCAConfig Config;

public GlobalSignRenewDomainRequest(GlobalSignCAConfig config)
{
Config = config;
}

public string MsslProfileId { get; set; } = string.Empty;
public string DomainId { get; set; } = string.Empty;

public BmV1RenewalDomainRequest Request
{
get
{
var request = new BmV1RenewalDomainRequest();
var header = new OrderRequestHeader
{
AuthToken = Config.GetOrderAuthToken()
};
request.OrderRequestHeader = header;
request.MSSLProfileID = MsslProfileId;
request.DomainID = DomainId;
request.VettingLevel = "OV";
request.VettingType = "DNS";
return request;
}
}
}
40 changes: 40 additions & 0 deletions globalsign-mssl-caplugin/Api/GlobalSignVerifyDomainRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright 2021 Keyfactor
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
// and limitations under the License.

using Order;

namespace Keyfactor.Extensions.CAPlugin.GlobalSign.Api;

public class GlobalSignVerifyDomainRequest
{
private readonly GlobalSignCAConfig Config;

public GlobalSignVerifyDomainRequest(GlobalSignCAConfig config)
{
Config = config;
}

public string DomainName { get; set; } = string.Empty;
public string DomainId { get; set; } = string.Empty;

public BmV1VerifyMsslDomainRequest Request
{
get
{
var request = new BmV1VerifyMsslDomainRequest();
var header = new OrderRequestHeader
{
AuthToken = Config.GetOrderAuthToken()
};
request.OrderRequestHeader = header;
request.DomainID = DomainId;
request.TagLocation = DomainName;
request.VettingType = "DNS";
return request;
}
}
}
42 changes: 42 additions & 0 deletions globalsign-mssl-caplugin/Client/GlobalSignApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,48 @@ public async Task<List<SearchMsslProfileDetail>> GetProfiles()
throw new Exception(gsError.Message);
}

public async Task<string> RenewDomain(GlobalSignRenewDomainRequest request)
{
Logger.MethodEntry();
var rawRequest = request.Request;
Logger.LogTrace($"Renew Domain request details:");
Logger.LogTrace($"Profile ID: {rawRequest.MSSLProfileID}");
Logger.LogTrace($"Domain ID: {rawRequest.DomainID}");
var responsewrapper = await OrderService.RenewalDomainAsync(new RenewalDomain(rawRequest));
var response = responsewrapper.Response;
if (response.OrderResponseHeader.SuccessCode == 0)
{
Logger.LogDebug("Renewal domain request successfully submitted");
Logger.MethodExit();
return response.DnsTXT;
}
var errorCode = int.Parse(response.OrderResponseHeader.Errors[0].ErrorCode);
var err = GlobalSignErrorIndex.GetGlobalSignError(errorCode);
Logger.MethodExit();
throw new Exception($"Error while attempting to renew domain: {err.DetailedMessage}");
}

public async Task<bool> VerifyDomain(GlobalSignVerifyDomainRequest request)
{
Logger.MethodEntry();
var rawRequest = request.Request;
Logger.LogTrace($"Verify Domain request details:");
Logger.LogTrace($"Domain Name: {rawRequest.TagLocation}");
Logger.LogTrace($"Domain ID: {rawRequest.DomainID}");
var responsewrapper = await OrderService.VerifyMsslDomainAsync(new VerifyMsslDomain(rawRequest));
var response = responsewrapper.Response;
if (response.OrderResponseHeader.SuccessCode == 0)
{
Logger.LogDebug("Verify domain request successful");
Logger.MethodExit();
return true;
}
var errorCode = int.Parse(response.OrderResponseHeader.Errors[0].ErrorCode);
var err = GlobalSignErrorIndex.GetGlobalSignError(errorCode);
Logger.MethodExit();
throw new Exception($"Error while attempting to verify domain: {err.DetailedMessage}");
}

public async Task<EnrollmentResult> Enroll(GlobalSignEnrollRequest enrollRequest)
{
Logger.MethodEntry();
Expand Down
1 change: 1 addition & 0 deletions globalsign-mssl-caplugin/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ internal class Constants
public static string SYNCINTERNVALDAYS = "SyncIntervalDays";
public static string SYNCPRODUCTS = "SyncProducts";
public static string Enabled = "Enabled";
public static string DNS_VALIDATION_ENABLED = "DnsValidationEnabled";
}

public static class EnrollmentConfigConstants
Expand Down
3 changes: 3 additions & 0 deletions globalsign-mssl-caplugin/GlobalSignCAConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ public class GlobalSignCAConfig

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

public bool DnsValidationEnabled { get; set; }


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