From e66af2ae2de2cf0c8909dfdec427692138216418 Mon Sep 17 00:00:00 2001 From: David Galey Date: Tue, 28 Jan 2025 08:38:21 -0500 Subject: [PATCH 1/2] Support subject/SANs outside of CSR --- src/GoogleCAProxy/GoogleCAProxy.cs | 67 ++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 7 deletions(-) diff --git a/src/GoogleCAProxy/GoogleCAProxy.cs b/src/GoogleCAProxy/GoogleCAProxy.cs index c628e5a..e8b543c 100644 --- a/src/GoogleCAProxy/GoogleCAProxy.cs +++ b/src/GoogleCAProxy/GoogleCAProxy.cs @@ -101,13 +101,47 @@ public override EnrollmentResult Enroll(ICertificateDataReader certificateDataRe $"LifetimeKey not found in Product Parameters for Product Id {productInfo.ProductID}. Using default value of 365 days."); } - Log.LogDebug($"Configuring {typeof(Certificate)} for {subject} with {lifetimeInDays} days validity"); + CertificateConfig certConfig = new CertificateConfig(); + certConfig.SubjectConfig = new CertificateConfig.Types.SubjectConfig(); + bool useConfig = false; + if (!string.IsNullOrEmpty(subject)) + { + certConfig.SubjectConfig.Subject = new Subject + { + CommonName = ParseSubject(subject, "CN=", false), + Organization = ParseSubject(subject, "O=", false), + OrganizationalUnit = ParseSubject(subject, "OU=", false), + CountryCode = ParseSubject(subject, "C=", false), + Locality = ParseSubject(subject, "L=", false) + }; + useConfig = true; + } + var dnsSans = new List(); + if (san != null & san.Count > 0) + { + var dnsKeys = san.Keys.Where(k => k.IndexOf("dns", StringComparison.OrdinalIgnoreCase) >= 0); + foreach (var key in dnsKeys) + { + dnsSans.AddRange(san[key]); + } + } + if (dnsSans.Count > 0) + { + certConfig.SubjectConfig.SubjectAltName = new SubjectAltNames + { + DnsNames = { dnsSans } + }; + useConfig = true; + } + + Log.LogDebug($"Configuring {typeof(Certificate)} for {subject} with {lifetimeInDays} days validity"); Certificate certificate = new Certificate { PemCsr = $"-----BEGIN NEW CERTIFICATE REQUEST-----\n{pemify(csr)}\n-----END NEW CERTIFICATE REQUEST-----", Lifetime = Duration.FromTimeSpan(new TimeSpan(lifetimeInDays, 0, 0, 0, - 0)) //365 day default or defined by config + 0)), //365 day default or defined by config + Config = (useConfig) ? certConfig : null }; if (productInfo.ProductID == NoTemplateProductId) @@ -660,11 +694,30 @@ private static CertificateAuthorityServiceClient BuildClient() return caClientBuilder.Build(); } - #endregion - - #region Obsolete Methods - - [Obsolete] + private static string ParseSubject(string subject, string rdn, bool required = true) + { + string escapedSubject = subject.Replace("\\,", "|"); + string rdnString = escapedSubject.Split(',').ToList().Where(x => x.Contains(rdn)).FirstOrDefault(); + + if (!string.IsNullOrEmpty(rdnString)) + { + return rdnString.Replace(rdn, "").Replace("|", ",").Trim(); + } + else if (required) + { + throw new Exception($"The request is missing a {rdn} value"); + } + else + { + return null; + } + } + + #endregion + + #region Obsolete Methods + + [Obsolete] public override EnrollmentResult Enroll(string csr, string subject, Dictionary san, EnrollmentProductInfo productInfo, PKIConstants.X509.RequestFormat requestFormat, RequestUtilities.EnrollmentType enrollmentType) From e5d09a9995b16d34aa2f77ab64c1cfd9aec66234 Mon Sep 17 00:00:00 2001 From: David Galey Date: Tue, 28 Jan 2025 08:43:09 -0500 Subject: [PATCH 2/2] Change CertificateID to be unique --- src/GoogleCAProxy/GoogleCAProxy.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/GoogleCAProxy/GoogleCAProxy.cs b/src/GoogleCAProxy/GoogleCAProxy.cs index e8b543c..09f9ab4 100644 --- a/src/GoogleCAProxy/GoogleCAProxy.cs +++ b/src/GoogleCAProxy/GoogleCAProxy.cs @@ -166,8 +166,7 @@ public override EnrollmentResult Enroll(ICertificateDataReader certificateDataRe ParentAsCaPoolName = caPoolAsTypedName, Certificate = certificate, //RequestId="",//if used, this needs to be durable between reties - CertificateId = - $"{now:yyyy}{now:MM}{now:dd}-{now:HH}{now:mm}{now:ss}" //ID is required for Enterprise tier CAs and ignored for other. + CertificateId = Guid.NewGuid().ToString() //ID is required for Enterprise tier CAs and ignored for other. }; if (!string.IsNullOrEmpty(CaId))