diff --git a/CHANGELOG.md b/CHANGELOG.md index b894178..46545d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,4 +17,7 @@ Convert GlobalSign status codes to Keyfactor status codes for syncing Fix authentication bug when picking up certificates 1.0.15 -Better datetime parsing of returned certificates \ No newline at end of file +Better datetime parsing of returned certificates + +1.0.16 +Fix for adding additional SANs to certificate requests diff --git a/README.md b/README.md index 1f84bae..abda15d 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,13 @@ + # GlobalSign Managed SSL AnyGateway This integration allows for the Synchronization, Enrollment, and Revocation of TLS Certificates from the GlobalSign Certificate Center. #### Integration status: Production - Ready for use in production environments. +## About the Keyfactor AnyCA Gateway DCOM Connector -## About the Keyfactor AnyGateway CA Connector - -This repository contains an AnyGateway CA Connector, which is a plugin to the Keyfactor AnyGateway. AnyGateway CA Connectors allow Keyfactor Command to be used for inventory, issuance, and revocation of certificates from a third-party certificate authority. - +This repository contains an AnyCA Gateway Connector, which is a plugin to the Keyfactor AnyGateway. AnyCA Gateway Connectors allow Keyfactor Command to be used for inventory, issuance, and revocation of certificates from a third-party certificate authority. ## Support for GlobalSign Managed SSL AnyGateway @@ -16,6 +15,8 @@ GlobalSign Managed SSL AnyGateway is supported by Keyfactor for Keyfactor custom ###### 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. +--- + --- @@ -23,6 +24,16 @@ GlobalSign Managed SSL AnyGateway is supported by Keyfactor for Keyfactor custom +## Keyfactor AnyCA Gateway Framework Supported +The Keyfactor gateway framework implements common logic shared across various gateway implementations and handles communication with Keyfactor Command. The gateway framework hosts gateway implementations or plugins that understand how to communicate with specific CAs. This allows you to integrate your third-party CAs with Keyfactor Command such that they behave in a manner similar to the CAs natively supported by Keyfactor Command. + + + + +This gateway extension was compiled against version of the AnyCA Gateway DCOM Framework. You will need at least this version of the framework Installed. If you have a later AnyGateway Framework Installed you will probably need to add binding redirects in the CAProxyServer.exe.config file to make things work properly. + + +[Keyfactor CAGateway Install Guide](https://software.keyfactor.com/Guides/AnyGateway_Generic/Content/AnyGateway/Introduction.htm) @@ -208,3 +219,4 @@ There are no specific Changes for the ServiceSettings section. Refer to the AnyG } ``` + diff --git a/src/GlobalSignCAProxy/Api/GlobalSignEnrollRequest.cs b/src/GlobalSignCAProxy/Api/GlobalSignEnrollRequest.cs index 038cee3..8a2f0fa 100644 --- a/src/GlobalSignCAProxy/Api/GlobalSignEnrollRequest.cs +++ b/src/GlobalSignCAProxy/Api/GlobalSignEnrollRequest.cs @@ -1,112 +1,142 @@ -// 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. - +// 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 CSS.Common.Logging; + using Keyfactor.Extensions.AnyGateway.GlobalSign.Services.Order; + using System.Collections.Generic; +using System.Linq; +using System.Text; namespace Keyfactor.Extensions.AnyGateway.GlobalSign.Api { - public class GlobalSignEnrollRequest - { - internal GlobalSignCAConfig Config; + public class GlobalSignEnrollRequest : LoggingClientBase + { + internal GlobalSignCAConfig Config; - public GlobalSignEnrollRequest(GlobalSignCAConfig config) - { - Config = config; - } - public string CSR { get; set; } - public string ProductCode { get; set; } - public string CommonName { get; set; } - public string BaseOption - { - get - { - if (!string.IsNullOrEmpty(CommonName)) - { - if (CommonName.StartsWith("*")) - { - return "wildcard"; - } - else - { - return null; - } - } - else - { - return null; - } - } - } - public string OrderKind { get; set; } - public string Licenses { get; set; } - public string Months { get; set; } - public string MsslProfileId { get; set; } - public string MsslDomainId { get; set; } - public string FirstName { get; set; } - public string LastName { get; set; } - public string Phone { get; set; } - public string Email { get; set; } - public List SANs { get; set; } - public PvSealInfo Seal { get; set; } - public MsslEvProfileInfo EVProfile { get; set; } - public BmV2PvOrderRequest Request - { - get - { - BmV2PvOrderRequest request = new BmV2PvOrderRequest(); - request.OrderRequestHeader = new OrderRequestHeader { AuthToken = Config.GetOrderAuthToken() }; - request.MSSLProfileID = MsslProfileId; - request.MSSLDomainID = MsslDomainId; - request.ContactInfo = new ContactInfo - { - FirstName = FirstName, - LastName = LastName, - Phone = Phone, - Email = Email - }; - if (SANs != null) - { - if (SANs.Count > 0) - { - List sans = new List(); - foreach (string item in SANs) - { - SANEntry entry = new SANEntry(); - entry.SubjectAltName = item; - if (item.StartsWith("*")) - { - entry.SubjectAltName = "13"; - } - else - { - entry.SubjectAltName = "7"; - } - } - request.SANEntries = sans.ToArray(); - } - } - ValidityPeriod validityPeriod = new ValidityPeriod(); - validityPeriod.Months = Months; - request.OrderRequestParameter = new OrderRequestParameter - { - ProductCode = ProductCode, - OrderKind = OrderKind, - Licenses = Licenses, - CSR = CSR, - ValidityPeriod = validityPeriod - }; - if (!string.IsNullOrEmpty(BaseOption)) - { - request.OrderRequestParameter.BaseOption = BaseOption; - } + public GlobalSignEnrollRequest(GlobalSignCAConfig config) + { + Config = config; + } + + public string CSR { get; set; } + public string ProductCode { get; set; } + public string CommonName { get; set; } + + public string BaseOption + { + get + { + if (!string.IsNullOrEmpty(CommonName)) + { + if (CommonName.StartsWith("*")) + { + return "wildcard"; + } + else + { + return null; + } + } + else + { + return null; + } + } + } + + public string OrderKind { get; set; } + public string Licenses { get; set; } + public string Months { get; set; } + public string MsslProfileId { get; set; } + public string MsslDomainId { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public string Phone { get; set; } + public string Email { get; set; } + public List SANs { get; set; } + public PvSealInfo Seal { get; set; } + public MsslEvProfileInfo EVProfile { get; set; } + + public BmV2PvOrderRequest Request + { + get + { + BmV2PvOrderRequest request = new BmV2PvOrderRequest(); + request.OrderRequestHeader = new OrderRequestHeader { AuthToken = Config.GetOrderAuthToken() }; + request.MSSLProfileID = MsslProfileId; + request.MSSLDomainID = MsslDomainId; + request.ContactInfo = new ContactInfo + { + FirstName = FirstName, + LastName = LastName, + Phone = Phone, + Email = Email + }; + if (SANs != null) + { + if (SANs.Count > 0) + { + List sans = new List(); + foreach (string item in SANs) + { + if (string.Equals(item, CommonName, System.StringComparison.OrdinalIgnoreCase)) + { + Logger.Info($"SAN Entry {item} matches CN, removing from request"); + continue; + } + SANEntry entry = new SANEntry(); + entry.SubjectAltName = item; + StringBuilder sb = new StringBuilder(); + sb.Append($"Adding SAN entry of type "); + if (item.StartsWith("*")) + { + entry.SANOptionType = "13"; + sb.Append("WILDCARD"); + } + else + { + entry.SANOptionType = "7"; + sb.Append("FQDN"); + } + sb.Append($" and value {item} to request"); + Logger.Info(sb.ToString()); + sans.Add(entry); + } + request.SANEntries = sans.ToArray(); + } + } + List