@@ -514,9 +514,15 @@ public static Dictionary<string, object> ReadCertTemplateProperties(ISearchResul
514514 if ( entry . GetIntProperty ( LDAPProperties . NumSignaturesRequired , out var authorizedSignatures ) )
515515 props . Add ( "authorizedsignatures" , authorizedSignatures ) ;
516516
517- props . Add ( "applicationpolicies" , entry . GetArrayProperty ( LDAPProperties . ApplicationPolicies ) ) ;
518- props . Add ( "issuancepolicies" , entry . GetArrayProperty ( LDAPProperties . IssuancePolicies ) ) ;
517+ bool hasUseLegacyProvider = false ;
518+ if ( entry . GetIntProperty ( LDAPProperties . PKIPrivateKeyFlag , out var privateKeyFlagsRaw ) )
519+ {
520+ var privateKeyFlags = ( PKIPrivateKeyFlag ) privateKeyFlagsRaw ;
521+ hasUseLegacyProvider = privateKeyFlags . HasFlag ( PKIPrivateKeyFlag . USE_LEGACY_PROVIDER ) ;
522+ }
519523
524+ props . Add ( "applicationpolicies" , ParseCertTemplateApplicationPolicies ( entry . GetArrayProperty ( LDAPProperties . ApplicationPolicies ) , schemaVersion , hasUseLegacyProvider ) ) ;
525+ props . Add ( "issuancepolicies" , entry . GetArrayProperty ( LDAPProperties . IssuancePolicies ) ) ;
520526
521527 // Construct effectiveekus
522528 string [ ] effectiveekus = schemaVersion == 1 & ekus . Length > 0 ? ekus : certificateapplicationpolicy ;
@@ -578,6 +584,33 @@ public Dictionary<string, object> ParseAllProperties(ISearchResultEntry entry)
578584 return props ;
579585 }
580586
587+ /// <summary>
588+ /// Parse CertTemplate attribute msPKI-RA-Application-Policies
589+ /// </summary>
590+ /// <param name="applicationPolicies"></param>
591+ /// <param name="schemaVersion"></param>
592+ /// <param name="hasUseLegacyProvider"></param>
593+ private static string [ ] ParseCertTemplateApplicationPolicies ( string [ ] applicationPolicies , int schemaVersion , bool hasUseLegacyProvider )
594+ {
595+ if ( applicationPolicies == null
596+ || applicationPolicies . Length == 0
597+ || schemaVersion == 1
598+ || schemaVersion == 2
599+ || ( schemaVersion == 4 && hasUseLegacyProvider ) ) {
600+ return applicationPolicies ;
601+ } else {
602+ // Format: "Name`Type`Value`Name`Type`Value`..."
603+ // (https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-crtd/c55ec697-be3f-4117-8316-8895e4399237)
604+ // Return the Value of Name = "msPKI-RA-Application-Policies" entries
605+ string [ ] entries = applicationPolicies [ 0 ] . Split ( '`' ) ;
606+ return Enumerable . Range ( 0 , entries . Length / 3 )
607+ . Select ( i => entries . Skip ( i * 3 ) . Take ( 3 ) . ToArray ( ) )
608+ . Where ( parts => parts . Length == 3 && parts [ 0 ] . Equals ( LDAPProperties . ApplicationPolicies , StringComparison . OrdinalIgnoreCase ) )
609+ . Select ( parts => parts [ 2 ] )
610+ . ToArray ( ) ;
611+ }
612+ }
613+
581614 /// <summary>
582615 /// Does a best guess conversion of the property to a type useable by the UI
583616 /// </summary>
0 commit comments