diff --git a/src/CommonLib/Processors/LDAPPropertyProcessor.cs b/src/CommonLib/Processors/LDAPPropertyProcessor.cs index e8262d90..e9b3b8a2 100644 --- a/src/CommonLib/Processors/LDAPPropertyProcessor.cs +++ b/src/CommonLib/Processors/LDAPPropertyProcessor.cs @@ -393,12 +393,22 @@ public async Task ReadComputerProperties(ISearchResultEntry return compProps; } + /// + /// Returns the properties associated with the RootCA + /// + /// + /// Returns a dictionary with the common properties of the RootCA public static Dictionary ReadRootCAProperties(ISearchResultEntry entry) { var props = GetCommonProps(entry); return props; } + /// + /// Returns the properties associated with the AIACA + /// + /// + /// Returns a dictionary with the common properties and the crosscertificatepair property of the AICA public static Dictionary ReadAIACAProperties(ISearchResultEntry entry) { var props = GetCommonProps(entry); @@ -413,28 +423,40 @@ public static Dictionary ReadEnterpriseCAProperties(ISearchResul return props; } + + /// + /// Returns the properties associated with the NTAuthStore. These properties will only contain common properties + /// + /// + /// Returns a dictionary with the common properties of the NTAuthStore public static Dictionary ReadNTAuthStoreProperties(ISearchResultEntry entry) { - var ntAuthStoreProps = new NTAuthStoreProperties - { - Props = GetCommonProps(entry) - }; - - return ntAuthStoreProps.Props; + var props = GetCommonProps(entry); + return props; } + /// + /// Reads specific LDAP properties related to CertTemplates + /// + /// + /// Returns a dictionary associated with the CertTemplate properties that were read public static Dictionary ReadCertTemplateProperties(ISearchResultEntry entry) { var props = GetCommonProps(entry); + props.Add("validityperiod", ConvertPKIPeriod(entry.GetByteProperty(LDAPProperties.PKIExpirationPeriod))); props.Add("renewalperiod", ConvertPKIPeriod(entry.GetByteProperty(LDAPProperties.PKIOverlappedPeriod))); + if (entry.GetIntProperty(LDAPProperties.TemplateSchemaVersion, out var schemaVersion)) props.Add("schemaversion", schemaVersion); + props.Add("displayname", entry.GetProperty(LDAPProperties.DisplayName)); props.Add("oid", entry.GetProperty(LDAPProperties.CertTemplateOID)); + if (entry.GetIntProperty(LDAPProperties.PKIEnrollmentFlag, out var enrollmentFlagsRaw)) { var enrollmentFlags = (PKIEnrollmentFlag)enrollmentFlagsRaw; + props.Add("enrollmentflag", enrollmentFlags); props.Add("requiresmanagerapproval", enrollmentFlags.HasFlag(PKIEnrollmentFlag.PEND_ALL_REQUESTS)); } @@ -442,6 +464,7 @@ public static Dictionary ReadCertTemplateProperties(ISearchResul if (entry.GetIntProperty(LDAPProperties.PKINameFlag, out var nameFlagsRaw)) { var nameFlags = (PKICertificateNameFlag)nameFlagsRaw; + props.Add("certificatenameflag", nameFlags); props.Add("enrolleesuppliessubject", nameFlags.HasFlag(PKICertificateNameFlag.ENROLLEE_SUPPLIES_SUBJECT)); @@ -453,9 +476,8 @@ public static Dictionary ReadCertTemplateProperties(ISearchResul props.Add("certificateapplicationpolicy", entry.GetArrayProperty(LDAPProperties.CertificateApplicationPolicy)); if (entry.GetIntProperty(LDAPProperties.NumSignaturesRequired, out var authorizedSignatures)) - { props.Add("authorizedsignatures", authorizedSignatures); - } + props.Add("applicationpolicies", entry.GetArrayProperty(LDAPProperties.ApplicationPolicies)); props.Add("issuancepolicies", entry.GetArrayProperty(LDAPProperties.IssuancePolicies)); @@ -539,7 +561,7 @@ private static object BestGuessConvert(string property) /// /// https://www.sysadmins.lv/blog-en/how-to-convert-pkiexirationperiod-and-pkioverlapperiod-active-directory-attributes.aspx /// - /// + /// Returns a string representing the time period associated with the input byte array in a human readable form private static string ConvertPKIPeriod(byte[] bytes) { if (bytes == null || bytes.Length == 0) @@ -642,10 +664,4 @@ public class ComputerProperties public TypedPrincipal[] SidHistory { get; set; } = Array.Empty(); public TypedPrincipal[] DumpSMSAPassword { get; set; } = Array.Empty(); } - - public class NTAuthStoreProperties - { - public Dictionary Props { get; set; } = new(); - public TypedPrincipal[] CertThumbprints { get; set; } = Array.Empty(); - } } \ No newline at end of file diff --git a/test/unit/LDAPPropertyTests.cs b/test/unit/LDAPPropertyTests.cs index 0c78389b..0a6c06df 100644 --- a/test/unit/LDAPPropertyTests.cs +++ b/test/unit/LDAPPropertyTests.cs @@ -603,6 +603,60 @@ public async Task LDAPPropertyProcessor_ReadComputerProperties_TestDumpSMSAPassw } + [Fact] + public void LDAPPropertyProcessor_ReadRootCAProperties() + { + var mock = new MockSearchResultEntry( + "CN\u003dDUMPSTER-DC01-CA,CN\u003dCERTIFICATION AUTHORITIES,CN\u003dPUBLIC KEY SERVICES,CN\u003dSERVICES,CN\u003dCONFIGURATION,DC\u003dDUMPSTER,DC\u003dFIRE", + new Dictionary + { + {"description", null}, + {"domain", "DUMPSTER.FIRE"}, + {"name", "DUMPSTER-DC01-CA@DUMPSTER.FIRE"}, + {"domainsid", "S-1-5-21-2697957641-2271029196-387917394"}, + {"whencreated", 1683986131}, + }, "2F9F3630-F46A-49BF-B186-6629994EBCF9", Label.RootCA); + + var test = LDAPPropertyProcessor.ReadRootCAProperties(mock); + var keys = test.Keys; + + //These are not common properties + Assert.DoesNotContain("domain", keys); + Assert.DoesNotContain("name", keys); + Assert.DoesNotContain("domainsid", keys); + + Assert.Contains("description", keys); + Assert.Contains("whencreated", keys); + } + + [Fact] + public void LDAPPropertyProcessor_ReadAIACAProperties() + { + var mock = new MockSearchResultEntry( + "CN\u003dDUMPSTER-DC01-CA,CN\u003dAIA,CN\u003dPUBLIC KEY SERVICES,CN\u003dSERVICES,CN\u003dCONFIGURATION,DC\u003dDUMPSTER,DC\u003dFIRE", + new Dictionary + { + {"description", null}, + {"domain", "DUMPSTER.FIRE"}, + {"name", "DUMPSTER-DC01-CA@DUMPSTER.FIRE"}, + {"domainsid", "S-1-5-21-2697957641-2271029196-387917394"}, + {"whencreated", 1683986131}, + {"crosscertificatepair", new[] + {"AQIDBAUGBwg="}} + }, "2F9F3630-F46A-49BF-B186-6629994EBCF9", Label.AIACA); + + var test = LDAPPropertyProcessor.ReadAIACAProperties(mock); + var keys = test.Keys; + + //These are not common properties + Assert.DoesNotContain("domain", keys); + Assert.DoesNotContain("name", keys); + Assert.DoesNotContain("domainsid", keys); + + Assert.Contains("description", keys); + Assert.Contains("whencreated", keys); + Assert.Contains("crosscertificatepair", keys); + } [Fact] public void LDAPPropertyProcessor_ReadNTAuthStoreProperties() @@ -620,11 +674,79 @@ public void LDAPPropertyProcessor_ReadNTAuthStoreProperties() var test = LDAPPropertyProcessor.ReadNTAuthStoreProperties(mock); var keys = test.Keys; + //These are not common properties + Assert.DoesNotContain("domain", keys); + Assert.DoesNotContain("name", keys); + Assert.DoesNotContain("domainsid", keys); + Assert.Contains("description", keys); Assert.Contains("whencreated", keys); } - // ReservedAttributes + [Fact] + public void LDAPPropertyProcessor_ReadCertTemplateProperties() + { + var mock = new MockSearchResultEntry("CN\u003dWORKSTATION,CN\u003dCERTIFICATE TEMPLATES,CN\u003dPUBLIC KEY SERVICES,CN\u003dSERVICES,CN\u003dCONFIGURATION,DC\u003dEXTERNAL,DC\u003dLOCAL", + new Dictionary + { + {"domain", "EXTERNAL.LOCAL"}, + {"name", "WORKSTATION@EXTERNAL.LOCAL"}, + {"domainsid", "S-1-5-21-3702535222-3822678775-2090119576"}, + {"description", null}, + {"whencreated", 1683986183}, + {"validityperiod", 31536000}, + {"renewalperiod", 3628800}, + {"schemaversion", 2}, + {"displayname", "Workstation Authentication"}, + {"oid", "1.3.6.1.4.1.311.21.8.4571196.1884641.3293620.10686285.12068043.134.1.30"}, + {"enrollmentflag", 32}, + {"requiresmanagerapproval", false}, + {"certificatenameflag", 134217728}, + {"enrolleesuppliessubject", false}, + {"subjectaltrequireupn", false}, + {"ekus", new[] + {"1.3.6.1.5.5.7.3.2"} + }, + {"certificateapplicationpolicy", new[] + {"1.3.6.1.5.5.7.3.2"} + }, + {"authorizedsignatures", 1}, + {"applicationpolicies", new[] + { "1.3.6.1.4.1.311.20.2.1"} + }, + {"issuancepolicies", new[] + {"1.3.6.1.4.1.311.21.8.4571196.1884641.3293620.10686285.12068043.134.1.400", + "1.3.6.1.4.1.311.21.8.4571196.1884641.3293620.10686285.12068043.134.1.402"} + }, + }, "2F9F3630-F46A-49BF-B186-6629994EBCF9", Label.CertTemplate); + + var test = LDAPPropertyProcessor.ReadCertTemplateProperties(mock); + var keys = test.Keys; + + //These are not common properties + Assert.DoesNotContain("domain", keys); + Assert.DoesNotContain("name", keys); + Assert.DoesNotContain("domainsid", keys); + + Assert.Contains("description", keys); + Assert.Contains("whencreated", keys); + Assert.Contains("validityperiod", keys); + Assert.Contains("renewalperiod", keys); + Assert.Contains("schemaversion", keys); + Assert.Contains("displayname", keys); + Assert.Contains("oid", keys); + Assert.Contains("enrollmentflag", keys); + Assert.Contains("requiresmanagerapproval", keys); + Assert.Contains("certificatenameflag", keys); + Assert.Contains("enrolleesuppliessubject", keys); + Assert.Contains("subjectaltrequireupn", keys); + Assert.Contains("ekus", keys); + Assert.Contains("certificateapplicationpolicy", keys); + Assert.Contains("authorizedsignatures", keys); + Assert.Contains("applicationpolicies", keys); + Assert.Contains("issuancepolicies", keys); + + } [Fact] public void LDAPPropertyProcessor_ParseAllProperties()