コード例 #1
0
ファイル: KrbApReq.cs プロジェクト: zha0/Kerberos.NET
        public static KrbApReq CreateApReq(
            KrbKdcRep tgsRep,
            KerberosKey authenticatorKey,
            ApOptions options,
            out KrbAuthenticator authenticator
            )
        {
            var ticket = tgsRep.Ticket;

            authenticator = new KrbAuthenticator
            {
                CName          = tgsRep.CName,
                Realm          = ticket.Realm,
                SequenceNumber = KerberosConstants.GetNonce(),
                Subkey         = KrbEncryptionKey.Generate(authenticatorKey.EncryptionType),
                Checksum       = KrbChecksum.EncodeDelegationChecksum(new DelegationInfo())
            };

            KerberosConstants.Now(out authenticator.CTime, out authenticator.CuSec);

            var apReq = new KrbApReq
            {
                Ticket        = ticket,
                ApOptions     = options,
                Authenticator = KrbEncryptedData.Encrypt(
                    authenticator.EncodeApplication(),
                    authenticatorKey,
                    KeyUsage.ApReqAuthenticator
                    )
            };

            return(apReq);
        }
コード例 #2
0
        public KileApRequest CreateApRequest(
            ApOptions apOptions,
            ChecksumType checksumType,
            int seqNumber,
            ChecksumFlags flag,
            EncryptionKey subkey,
            AuthorizationData authorizationData)
        {
            var request = new KileApRequest(context);

            request.Authenticator = CreateAuthenticator(
                checksumType,
                seqNumber,
                flag,
                subkey,
                authorizationData,
                context.ApSessionKey,
                null);

            request.Request.ap_options = new APOptions(KerberosUtility.ConvertInt2Flags((int)apOptions));
            request.Request.msg_type   = new Asn1Integer((int)MsgType.KRB_AP_REQ);
            request.Request.pvno       = new Asn1Integer(ConstValue.KERBEROSV5);
            request.Request.ticket     = context.ApTicket;

            return(request);
        }
コード例 #3
0
        /// <summary>
        /// Create AP request and encode to GSSAPI token
        /// </summary>
        /// <param name="apOptions">AP options</param>
        /// <param name="data">Authorization data</param>
        /// <param name="subkey">Sub-session key in authenticator</param>
        /// <param name="checksumFlags">Checksum flags</param>
        /// <returns></returns>
        private byte[] CreateGssApiToken(ApOptions apOptions, AuthorizationData data, EncryptionKey subkey, ChecksumFlags checksumFlags, KerberosConstValue.GSSToken gssToken = KerberosConstValue.GSSToken.GSSSPNG)
        {
            APOptions options = new APOptions(KerberosUtility.ConvertInt2Flags((int)apOptions));

            Authenticator authenticator = CreateAuthenticator(Context.Ticket, data, subkey, checksumFlags);

            this.ApRequestAuthenticator = authenticator;
            KerberosApRequest request = new KerberosApRequest(
                Context.Pvno,
                options,
                Context.Ticket,
                authenticator,
                KeyUsageNumber.AP_REQ_Authenticator
                );

            this.client.UpdateContext(request);

            if ((this.Context.ChecksumFlag & ChecksumFlags.GSS_C_DCE_STYLE) == ChecksumFlags.GSS_C_DCE_STYLE)
            {
                return(request.ToBytes());
            }
            else
            {
                return(KerberosUtility.AddGssApiTokenHeader(request, this.client.OidPkt, gssToken));
            }
        }
コード例 #4
0
 public KileApRequest CreateApRequest(ApOptions apOptions,
                                      ChecksumType checksumType,
                                      int seqNumber,
                                      ChecksumFlags flag,
                                      EncryptionKey subkey,
                                      AuthorizationData authorizationData)
 {
     return(CreateApRequest(context.UserRealm, context.UserName, apOptions, checksumType, seqNumber, flag,
                            subkey, authorizationData));
 }
コード例 #5
0
        /// <summary>
        /// Get the ApOptions flag and Checksum flag by the context attribute
        /// </summary>
        /// <param name="apOption">The apOptions flag</param>
        /// <param name="checksumFlags">The checksum flag</param>
        private void GetFlagsByContextAttribute(out ApOptions apOptions, out ChecksumFlags checksumFlags)
        {
            apOptions     = ApOptions.None;
            checksumFlags = ChecksumFlags.None;

            if ((contextAttribute & ClientSecurityContextAttribute.Delegate) == ClientSecurityContextAttribute.Delegate)
            {
                throw new NotSupportedException("ContextAttribute.Delegate is not supported currently!");
            }
            if ((contextAttribute & ClientSecurityContextAttribute.UseSessionKey)
                == ClientSecurityContextAttribute.UseSessionKey)
            {
                throw new NotSupportedException("ContextAttribute.UseSessionKey is not supported currently!");
            }
            if ((contextAttribute & ClientSecurityContextAttribute.MutualAuth)
                == ClientSecurityContextAttribute.MutualAuth)
            {
                checksumFlags |= ChecksumFlags.GSS_C_MUTUAL_FLAG;
                apOptions     |= ApOptions.MutualRequired;
            }
            if ((contextAttribute & ClientSecurityContextAttribute.ReplayDetect)
                == ClientSecurityContextAttribute.ReplayDetect)
            {
                checksumFlags |= ChecksumFlags.GSS_C_REPLAY_FLAG;
            }
            if ((contextAttribute & ClientSecurityContextAttribute.SequenceDetect)
                == ClientSecurityContextAttribute.SequenceDetect)
            {
                checksumFlags |= ChecksumFlags.GSS_C_SEQUENCE_FLAG;
            }
            if ((contextAttribute & ClientSecurityContextAttribute.Confidentiality)
                == ClientSecurityContextAttribute.Confidentiality)
            {
                checksumFlags |= ChecksumFlags.GSS_C_CONF_FLAG;
            }
            if ((contextAttribute & ClientSecurityContextAttribute.DceStyle) == ClientSecurityContextAttribute.DceStyle)
            {
                checksumFlags |= ChecksumFlags.GSS_C_DCE_STYLE;
            }
            if ((contextAttribute & ClientSecurityContextAttribute.ExtendedError)
                == ClientSecurityContextAttribute.ExtendedError)
            {
                checksumFlags |= ChecksumFlags.GSS_C_EXTENDED_ERROR_FLAG;
            }
            if ((contextAttribute & ClientSecurityContextAttribute.Integrity)
                == ClientSecurityContextAttribute.Integrity)
            {
                checksumFlags |= ChecksumFlags.GSS_C_INTEG_FLAG;
            }
            if ((contextAttribute & ClientSecurityContextAttribute.Identify) == ClientSecurityContextAttribute.Identify)
            {
                checksumFlags |= ChecksumFlags.GSS_C_IDENTIFY_FLAG;
            }
        }
コード例 #6
0
        /// <summary>
        /// Get the ApOptions flag and Checksum flag by the context attribute
        /// </summary>
        /// <param name="apOption">The apOptions flag</param>
        /// <param name="checksumFlags">The checksum flag</param>
        private void GetFlagsByContextAttribute(out ApOptions apOptions)
        {
            apOptions = ApOptions.MutualRequired;
            var checksumFlags = ChecksumFlags.None;

            if ((contextAttribute & ClientSecurityContextAttribute.Delegate) == ClientSecurityContextAttribute.Delegate)
            {
                checksumFlags |= ChecksumFlags.GSS_C_DELEG_FLAG;
            }
            if ((contextAttribute & ClientSecurityContextAttribute.MutualAuth)
                == ClientSecurityContextAttribute.MutualAuth)
            {
                checksumFlags |= ChecksumFlags.GSS_C_MUTUAL_FLAG;
                apOptions     |= ApOptions.MutualRequired;
            }
            if ((contextAttribute & ClientSecurityContextAttribute.ReplayDetect)
                == ClientSecurityContextAttribute.ReplayDetect)
            {
                checksumFlags |= ChecksumFlags.GSS_C_REPLAY_FLAG;
            }
            if ((contextAttribute & ClientSecurityContextAttribute.SequenceDetect)
                == ClientSecurityContextAttribute.SequenceDetect)
            {
                checksumFlags |= ChecksumFlags.GSS_C_SEQUENCE_FLAG;
            }
            if ((contextAttribute & ClientSecurityContextAttribute.Confidentiality)
                == ClientSecurityContextAttribute.Confidentiality)
            {
                apOptions      = ApOptions.None;
                checksumFlags |= ChecksumFlags.GSS_C_CONF_FLAG;
            }
            if ((contextAttribute & ClientSecurityContextAttribute.DceStyle) == ClientSecurityContextAttribute.DceStyle)
            {
                checksumFlags |= ChecksumFlags.GSS_C_DCE_STYLE;
            }
            if ((contextAttribute & ClientSecurityContextAttribute.ExtendedError)
                == ClientSecurityContextAttribute.ExtendedError)
            {
                checksumFlags |= ChecksumFlags.GSS_C_EXTENDED_ERROR_FLAG;
            }
            if ((contextAttribute & ClientSecurityContextAttribute.Integrity)
                == ClientSecurityContextAttribute.Integrity)
            {
                checksumFlags |= ChecksumFlags.GSS_C_INTEG_FLAG;
            }
            if ((contextAttribute & ClientSecurityContextAttribute.Identify) == ClientSecurityContextAttribute.Identify)
            {
                checksumFlags |= ChecksumFlags.GSS_C_IDENTIFY_FLAG;
            }

            this.Context.ChecksumFlag = checksumFlags;
        }
コード例 #7
0
        internal void Encode(AsnWriter writer, Asn1Tag tag)
        {
            writer.PushSequence(tag);

            writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 0));
            writer.WriteInteger(ProtocolVersionNumber);
            writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 0));
            writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 1));
            writer.WriteInteger((long)MessageType);
            writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 1));
            writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 2));
            writer.WriteBitString(ApOptions.AsReadOnly());
            writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 2));
            writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 3));
            Ticket?.Encode(writer);
            writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 3));
            writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 4));
            Authenticator?.Encode(writer);
            writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 4));
            writer.PopSequence(tag);
        }
コード例 #8
0
        public KileApRequest CreateApRequest(
            Realm cRealm,
            PrincipalName cName,
            ApOptions apOptions,
            ChecksumType checksumType,
            int seqNumber,
            ChecksumFlags flag,
            EncryptionKey subkey,
            AuthorizationData authorizationData)
        {
            if (cRealm == null)
            {
                throw new ArgumentNullException("cRealm");
            }
            if (cName == null)
            {
                throw new ArgumentNullException("cName");
            }
            KileApRequest request = new KileApRequest(context);

            request.Authenticator = CreateAuthenticator(cRealm,
                                                        cName,
                                                        checksumType,
                                                        seqNumber,
                                                        flag,
                                                        subkey,
                                                        authorizationData,
                                                        context.ApSessionKey,
                                                        null);

            request.Request.ap_options = new APOptions(KileUtility.ConvertInt2Flags((int)apOptions));
            request.Request.msg_type   = new Asn1Integer((int)MsgType.KRB_AP_REQ);
            request.Request.pvno       = new Asn1Integer(ConstValue.KERBEROSV5);
            request.Request.ticket     = context.ApTicket;

            return(request);
        }
コード例 #9
0
        //TODO...
        //askTGS with TGT kirbi
        public static async System.Threading.Tasks.Task <TicketFlags> askTGS2(string kdc,
                                                                              ILoggerFactory logger,
                                                                              TcpKerberosTransport transport,
                                                                              KrbAsRep asRep,
                                                                              string username,
                                                                              string password,
                                                                              string domainName,
                                                                              string spn,
                                                                              bool isUnconstrained    = false,
                                                                              bool outKirbi           = false,
                                                                              bool verbose            = false,
                                                                              bool kerberoast         = false,
                                                                              bool ptt                = false,
                                                                              string hash             = null,
                                                                              EncryptionType etype    = EncryptionType.RC4_HMAC_NT,
                                                                              bool outfile            = false,
                                                                              string srvName          = null,
                                                                              string tgsHash          = null,
                                                                              EncryptionType tgsEtype = EncryptionType.AES256_CTS_HMAC_SHA1_96
                                                                              )
        {
            var now = DateTime.Now;

            credKey = password != null ?
                      new KerberosPasswordCredential(username, password, domainName).CreateKey() :
                      new Utils.KerberosHashCreds(username, hash, etype, domainName).CreateKey();


            KrbEncAsRepPart asDecrypted = cred.DecryptKdcRep(
                asRep,
                KeyUsage.EncAsRepPart,
                d => KrbEncAsRepPart.DecodeApplication(d));

            var sessionKey = asDecrypted.Key;



            //Request Service Ticket parameters

            ApOptions  apOptions  = ApOptions.Reserved;
            KdcOptions kdcOptions =
                KdcOptions.Forwardable |
                KdcOptions.Renewable |
                KdcOptions.RenewableOk |
                KdcOptions.Canonicalize;
            string    s4u             = null;
            KrbTicket s4uTicket       = null;
            KrbTicket u2uServerTicket = null;

            if (isUnconstrained)
            {
                spn         = $"krbtgt/{domainName}";
                kdcOptions |= KdcOptions.Forwarded;
            }


            var rst = new RequestServiceTicket()
            {
                ServicePrincipalName = spn,
                ApOptions            = apOptions,
                S4uTarget            = s4u,
                S4uTicket            = s4uTicket,
                UserToUserTicket     = u2uServerTicket,
                KdcOptions           = kdcOptions,
                Realm = domainName
            };


            var sname = rst.ServicePrincipalName.Split('/', '@');
            var tgt   = asRep.Ticket;

            var additionalTickets = new List <KrbTicket>();

            if (rst.KdcOptions.HasFlag(KdcOptions.EncTktInSkey) && rst.UserToUserTicket != null)
            {
                additionalTickets.Add(rst.UserToUserTicket);
            }
            if (!string.IsNullOrWhiteSpace(rst.S4uTarget))
            {
                rst.KdcOptions |= KdcOptions.Forwardable;
            }
            if (rst.S4uTicket != null)
            {
                rst.KdcOptions |= KdcOptions.ConstrainedDelegation;

                additionalTickets.Add(rst.S4uTicket);
            }


            var body = new KrbKdcReqBody
            {
                //Specify RC4 as the only supported EType
                EType      = new[] { EncryptionType.RC4_HMAC_NT },//KrbConstants.KerberosConstants.ETypes.ToArray(),
                KdcOptions = rst.KdcOptions,
                Nonce      = KrbConstants.KerberosConstants.GetNonce(),
                Realm      = rst.Realm,
                SName      = new KrbPrincipalName()
                {
                    Type = PrincipalNameType.NT_SRV_INST,
                    Name = sname
                },
                Till  = KrbConstants.KerberosConstants.EndOfTime,
                CName = rst.CNameHint
            };

            if (additionalTickets.Count > 0)
            {
                body.AdditionalTickets = additionalTickets.ToArray();
            }

            var bodyChecksum = KrbChecksum.Create(
                body.Encode(),
                sessionKey.AsKey(),
                KeyUsage.PaTgsReqChecksum
                );

            //ApReq
            //Authenticator
            var authenticator = new KrbAuthenticator
            {
                CName          = asRep.CName,
                Realm          = asRep.Ticket.Realm,
                SequenceNumber = KrbConstants.KerberosConstants.GetNonce(),
                Checksum       = bodyChecksum,
                CTime          = now,
                CuSec          = now.Millisecond //new Random().Next(0, 999999)
            };

            var subSessionKey = KrbEncryptionKey.Generate(sessionKey.EType);

            subSessionKey.Usage  = KeyUsage.EncTgsRepPartSubSessionKey;
            authenticator.Subkey = subSessionKey;

            var encryptedAuthenticator = KrbEncryptedData.Encrypt(
                authenticator.EncodeApplication(),
                sessionKey.AsKey(),
                KeyUsage.PaTgsReqAuthenticator
                );

            var apReq = new KrbApReq
            {
                Ticket        = tgt,
                ApOptions     = apOptions,
                Authenticator = encryptedAuthenticator
            };


            var pacOptions = new KrbPaPacOptions
            {
                Flags = PacOptions.BranchAware
            }.Encode();

            var paData = new List <KrbPaData>()
            {
                new KrbPaData
                {
                    Type  = PaDataType.PA_TGS_REQ,
                    Value = apReq.EncodeApplication()
                },
                new KrbPaData
                {
                    Type  = PaDataType.PA_PAC_OPTIONS,
                    Value = pacOptions
                }
            };



            if (!string.IsNullOrWhiteSpace(rst.S4uTarget))
            {
                var paS4u = new KrbPaForUser
                {
                    AuthPackage = "Kerberos",
                    UserName    = new KrbPrincipalName {
                        Type = PrincipalNameType.NT_ENTERPRISE, Name = new[] { s4u }
                    },
                    UserRealm = tgt.Realm
                };
                paS4u.GenerateChecksum(subSessionKey.AsKey());

                paData.Add(new KrbPaData
                {
                    Type  = PaDataType.PA_FOR_USER,
                    Value = paS4u.Encode()
                });
            }

            var tgs = new KrbTgsReq
            {
                PaData = paData.ToArray(),
                Body   = body
            };



            ReadOnlyMemory <byte> encodedTgs = tgs.EncodeApplication();


            Console.WriteLine("[*] Sending TGS-REQ ...");
            if (verbose)
            {
                PrintFunc.PrintReq(tgs, credKey, sessionKey.AsKey());
            }



            CancellationToken cancellation = default;

            cancellation.ThrowIfCancellationRequested();



            KrbTgsRep tgsRep = null;

            try
            {
                tgsRep = await transport.SendMessage <KrbTgsRep>(
                    rst.Realm,
                    encodedTgs,
                    cancellation
                    );
            }
            catch (KerberosProtocolException pex)
            {
                Console.WriteLine("[x] Kerberos Error: {0}\n", pex.Message);
                Environment.Exit(0);
            }


            Console.WriteLine("[*] Receiving TGS-REP ...");
            if (verbose)
            {
                PrintFunc.PrintRep(tgsRep, credKey);
            }



            var returnFlag = TicketFlags.Anonymous;

            try
            {
                //TGS-REP Enc-Part
                //https://github.com/dotnet/Kerberos.NET/blob/develop/Kerberos.NET/Entities/Krb/KrbTgsReq.cs#L144
                KrbEncTgsRepPart tgsDecryptedRepPart = tgsRep.EncPart.Decrypt <KrbEncTgsRepPart>(
                    subSessionKey.AsKey(),
                    KeyUsage.EncTgsRepPartSubSessionKey,
                    (ReadOnlyMemory <byte> t) => KrbEncTgsRepPart.DecodeApplication(t));

                if (verbose)
                {
                    Console.WriteLine("    * [Decrypted Enc-Part]:");
                    PrintFunc.PrintRepEnc(tgsDecryptedRepPart, credKey);

                    returnFlag = tgsDecryptedRepPart.Flags;


                    if (!string.IsNullOrEmpty(tgsHash))
                    {
                        //=========================================
                        //TGS Tiket Enc-Part
                        //Service account Cred
                        var kerbCred2 = new Utils.KerberosHashCreds(srvName, tgsHash, tgsEtype);

                        //TGS-REQ Ticket Enc-Part
                        KrbEncTicketPart ticketDecrypted = tgsRep.Ticket.EncryptedPart.Decrypt <KrbEncTicketPart>
                                                               (kerbCred2.CreateKey(),
                                                               KeyUsage.Ticket,
                                                               (ReadOnlyMemory <byte> t) => KrbEncTicketPart.DecodeApplication(t));

                        Console.WriteLine("    * [Decrypted Ticket Enc-Part]:");
                        PrintFunc.PrintTicketEnc(ticketDecrypted);
                        //=========================================
                    }
                }


                if (outKirbi || outfile)
                {
                    var kirbiTGS = Kirbi.toKirbi(tgsRep, tgsDecryptedRepPart, ptt);
                    if (outKirbi)
                    {
                        Console.WriteLine("[+] TGS Kirbi:");
                        Console.WriteLine("    - {0}", Convert.ToBase64String(kirbiTGS));
                    }
                    if (outfile)
                    {
                        Utils.Utils.WriteBytesToFile(Utils.Utils.MakeTicketFileName(username, sname), kirbiTGS);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("[x] {0}", e.Message);
            }



            if (kerberoast)
            {
                //Kerberoasting
                var encType    = (int)Enum.Parse(typeof(EncryptionType), tgsRep.Ticket.EncryptedPart.EType.ToString());
                var myCipher   = (BitConverter.ToString(tgsRep.Ticket.EncryptedPart.Cipher.ToArray())).Replace("-", "");
                var kroasthash = String.Format("$krb5tgs${0}$*{1}${2}${3}*${4}${5}", encType, username, domainName, spn, myCipher.Substring(0, 32), myCipher.Substring(32));
                Console.WriteLine("[+] Kerberoasting Hash: {0}", kroasthash);
            }


            return(returnFlag);
        }
コード例 #10
0
        public static KrbApReq CreateApReq(KrbKdcRep tgsRep, KerberosKey authenticatorKey, ApOptions options)
        {
            var ticket = tgsRep.Ticket;

            KerberosConstants.Now(out DateTimeOffset time, out int usec);

            var authenticator = new KrbAuthenticator
            {
                CName                      = tgsRep.CName,
                CTime                      = time,
                Cusec                      = usec,
                Realm                      = ticket.Realm,
                SequenceNumber             = KerberosConstants.GetNonce(),
                Subkey                     = null,
                AuthenticatorVersionNumber = 5
            };

            var apReq = new KrbApReq
            {
                Ticket        = ticket,
                ApOptions     = options,
                Authenticator = KrbEncryptedData.Encrypt(
                    authenticator.EncodeApplication(),
                    authenticatorKey,
                    KeyUsage.ApReqAuthenticator
                    )
            };

            return(apReq);
        }
コード例 #11
0
ファイル: S4U.cs プロジェクト: zhouzu/KerberosRun
        //S4U2Proxy
        //[MS-SFU] 3.2.5.2.1.2 Using ServicesAllowedToSendForwardedTicketsTo
        //The KDC checks if the security principal name(SPN) for Service 2,
        //identified in the sname and srealm fields of the KRB_TGS_REQ message,
        //is in the Service 1 account's ServicesAllowedToSendForwardedTicketsTo parameter.
        //If it is, then the KDC replies with a service ticket for Service 2.
        //Otherwise the KDC MUST return `KRB-ERR-BADOPTION`.
        public static async System.Threading.Tasks.Task S4U2Proxy(string kdc,
                                                                  ILoggerFactory logger,
                                                                  TcpKerberosTransport transport,
                                                                  KrbAsRep asRep,
                                                                  KrbTgsRep s4u2self,
                                                                  string username,
                                                                  string password,
                                                                  string domainName,
                                                                  string impersonateuser,
                                                                  string spn,
                                                                  bool outKirbi        = false,
                                                                  bool verbose         = false,
                                                                  bool ptt             = false,
                                                                  string hash          = null,
                                                                  EncryptionType etype = EncryptionType.RC4_HMAC_NT)
        {
            var now = DateTime.UtcNow;

            credKey = password != null ?
                      new KerberosPasswordCredential(username, password, domainName).CreateKey() :
                      new Utils.KerberosHashCreds(username, hash, etype, domainName).CreateKey();


            KrbEncAsRepPart asDecrypted = password != null ?
                                          new KerberosPasswordCredential(username, password, domainName).DecryptKdcRep(
                asRep,
                KeyUsage.EncAsRepPart,
                d => KrbEncAsRepPart.DecodeApplication(d)) :
                                          new Utils.KerberosHashCreds(username, hash, etype, domainName).DecryptKdcRep(
                asRep,
                KeyUsage.EncAsRepPart,
                d => KrbEncAsRepPart.DecodeApplication(d));

            var sessionKey = asDecrypted.Key;


            //Request Service Ticket parameters

            ApOptions  apOptions  = ApOptions.Reserved;
            KdcOptions kdcOptions =
                KdcOptions.Forwardable |
                KdcOptions.Renewable |
                KdcOptions.RenewableOk;
            string    s4u             = null;
            KrbTicket s4uTicket       = s4u2self.Ticket;
            KrbTicket u2uServerTicket = null;



            var rst = new RequestServiceTicket()
            {
                ServicePrincipalName = spn,
                ApOptions            = apOptions,
                S4uTarget            = s4u,
                S4uTicket            = s4uTicket,
                UserToUserTicket     = u2uServerTicket,
                KdcOptions           = kdcOptions,
                Realm = domainName
            };


            var sname = rst.ServicePrincipalName.Split('/', '@');
            var tgt   = asRep.Ticket;

            var additionalTickets = new List <KrbTicket>();

            if (rst.KdcOptions.HasFlag(KdcOptions.EncTktInSkey) && rst.UserToUserTicket != null)
            {
                additionalTickets.Add(rst.UserToUserTicket);
            }
            if (!string.IsNullOrWhiteSpace(rst.S4uTarget))
            {
                rst.KdcOptions |= KdcOptions.Forwardable;
            }
            if (rst.S4uTicket != null)
            {
                rst.KdcOptions = rst.KdcOptions | KdcOptions.ConstrainedDelegation | KdcOptions.CNameInAdditionalTicket;

                additionalTickets.Add(rst.S4uTicket);
            }

            //EncryptionType[] kdcReqEtype = { EncryptionType.RC4_HMAC_NT };
            string[] name = { };
            var      body = new KrbKdcReqBody
            {
                EType      = KrbConstants.KerberosConstants.ETypes.ToArray(),
                KdcOptions = rst.KdcOptions,
                Nonce      = KrbConstants.KerberosConstants.GetNonce(),
                Realm      = rst.Realm,
                SName      = new KrbPrincipalName()
                {
                    Type = PrincipalNameType.NT_SRV_INST,
                    Name = sname
                },
                Till  = KrbConstants.KerberosConstants.EndOfTime,
                CName = new KrbPrincipalName()
                {
                    Type = PrincipalNameType.NT_SRV_INST,
                    Name = name
                },
            };

            if (additionalTickets.Count > 0)
            {
                body.AdditionalTickets = additionalTickets.ToArray();
            }

            var bodyChecksum = KrbChecksum.Create(
                body.Encode(),
                sessionKey.AsKey(),
                KeyUsage.PaTgsReqChecksum
                );


            //ApReq
            //Authenticator
            var authenticator = new KrbAuthenticator
            {
                CName          = asRep.CName,
                Realm          = asRep.Ticket.Realm,
                SequenceNumber = KrbConstants.KerberosConstants.GetNonce(),
                Checksum       = bodyChecksum,
                CTime          = now,
                CuSec          = now.Millisecond //new Random().Next(0, 999999)
            };

            var subSessionKey = KrbEncryptionKey.Generate(sessionKey.EType);

            subSessionKey.Usage  = KeyUsage.EncTgsRepPartSubSessionKey;
            authenticator.Subkey = subSessionKey;

            var encryptedAuthenticator = KrbEncryptedData.Encrypt(
                authenticator.EncodeApplication(),
                sessionKey.AsKey(),
                KeyUsage.PaTgsReqAuthenticator
                );

            var apReq = new KrbApReq
            {
                Ticket        = tgt,
                ApOptions     = apOptions,
                Authenticator = encryptedAuthenticator
            };


            var pacOptions = new KrbPaPacOptions
            {
                Flags = PacOptions.ResourceBasedConstrainedDelegation
            }.Encode();

            var paData = new List <KrbPaData>()
            {
                new KrbPaData
                {
                    Type  = PaDataType.PA_TGS_REQ,
                    Value = apReq.EncodeApplication()
                },
                new KrbPaData
                {
                    Type  = PaDataType.PA_PAC_OPTIONS,
                    Value = pacOptions
                }
            };



            if (!string.IsNullOrWhiteSpace(rst.S4uTarget))
            {
                var paS4u = new KrbPaForUser
                {
                    AuthPackage = "Kerberos",
                    UserName    = new KrbPrincipalName {
                        Type = PrincipalNameType.NT_ENTERPRISE, Name = new[] { s4u }
                    },
                    UserRealm = tgt.Realm
                };
                paS4u.GenerateChecksum(subSessionKey.AsKey());

                paData.Add(new KrbPaData
                {
                    Type  = PaDataType.PA_FOR_USER,
                    Value = paS4u.Encode()
                });
            }

            var tgs = new KrbTgsReq
            {
                PaData = paData.ToArray(),
                Body   = body
            };



            ReadOnlyMemory <byte> encodedTgs = tgs.EncodeApplication();


            Console.WriteLine("[*] Sending TGS-REQ [S4U2Proxy] ...");
            if (verbose)
            {
                PrintFunc.PrintReq(tgs, credKey, sessionKey.AsKey());
            }



            CancellationToken cancellation = default;

            cancellation.ThrowIfCancellationRequested();



            KrbTgsRep tgsRep = null;

            try
            {
                tgsRep = await transport.SendMessage <KrbTgsRep>(
                    rst.Realm,
                    encodedTgs,
                    cancellation
                    );
            }
            catch (KerberosProtocolException pex)
            {
                Console.WriteLine("[x] Kerberos Error: {0}", pex.Message);
                Environment.Exit(0);
            }


            Console.WriteLine("[*] Receiving TGS-REP [S4U2Proxy] ...");

            try
            {
                KrbEncTgsRepPart tgsDecryptedRepPart = tgsRep.EncPart.Decrypt <KrbEncTgsRepPart>(
                    subSessionKey.AsKey(),
                    KeyUsage.EncTgsRepPartSubSessionKey,
                    (ReadOnlyMemory <byte> t) => KrbEncTgsRepPart.DecodeApplication(t));

                if (verbose)
                {
                    PrintFunc.PrintRep(tgsRep, credKey);

                    Console.WriteLine("    * [Decrypted Enc-Part]:");
                    PrintFunc.PrintRepEnc(tgsDecryptedRepPart, credKey);
                }

                if (outKirbi)
                {
                    var kirbiTGS = Kirbi.toKirbi(tgsRep, tgsDecryptedRepPart, ptt);

                    Console.WriteLine("[+] TGS Kirbi:");
                    Console.WriteLine("    - {0}", Convert.ToBase64String(kirbiTGS));
                }
            }catch (Exception e)
            {
                Console.WriteLine("[x] {0}", e.Message);
            }
        }
        /// <summary>
        /// Create and send FAST TGS request
        /// </summary>
        /// <param name="sName">Service principal name</param>
        /// <param name="kdcOptions">KDC options</param>
        /// <param name="innerSeqPaData">A sequence of preauthentication data in FAST request</param>
        /// <param name="outerSeqPaData">A sequence of preauthentication data</param>
        /// <param name="subKey">Sub-session key for authenticator in FAST armor field</param>
        /// <param name="fastOptions">FAST options</param>
        /// <param name="apOptions">AP options in FAST armor field</param>
        /// <param name="data">Authorization data</param>
        public void SendTgsRequestWithExplicitFast(
            string sName,
            KdcOptions kdcOptions,
            Asn1SequenceOf<PA_DATA> innerSeqPaData,
            Asn1SequenceOf<PA_DATA> outerSeqPaData,
            EncryptionKey subKey,
            FastOptions fastOptions,
            ApOptions apOptions,
            AuthorizationData data = null)
        {
            Context.Subkey = subKey;
            Context.ReplyKey = subKey;
            string domain = this.Context.Realm.Value;
            PrincipalName sname = new PrincipalName(new KerbInt32((int)PrincipalType.NT_SRV_INST),
                KerberosUtility.String2SeqKerbString(sName.Split('/')));

            KDC_REQ_BODY kdcReqBody = CreateKdcRequestBody(kdcOptions, sname, data);
            Asn1BerEncodingBuffer bodyBuffer = new Asn1BerEncodingBuffer();
            kdcReqBody.BerEncode(bodyBuffer);

            //Create PA-TGS-REQ
            APOptions option = new APOptions(KerberosUtility.ConvertInt2Flags((int)ApOptions.None));
            ChecksumType checksumType = KerberosUtility.GetChecksumType(Context.SelectedEType);
            KerberosApRequest apRequest = CreateApRequest(
                option,
                Context.Ticket,
                subKey,
                data,
                KeyUsageNumber.TG_REQ_PA_TGS_REQ_padataOR_AP_REQ_Authenticator,
                checksumType,
                bodyBuffer.Data);

            PaTgsReq paTgsReq = new PaTgsReq(apRequest.Request);

            Asn1SequenceOf<PA_DATA> tempPaData = null;
            if (outerSeqPaData == null || outerSeqPaData.Elements == null || outerSeqPaData.Elements.Length == 0)
            {
                tempPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paTgsReq.Data });
            }
            else
            {
                tempPaData.Elements = new PA_DATA[outerSeqPaData.Elements.Length + 1];
                Array.Copy(outerSeqPaData.Elements, tempPaData.Elements, outerSeqPaData.Elements.Length);
                tempPaData.Elements[outerSeqPaData.Elements.Length] = paTgsReq.Data;
            }
            //Create explicit FAST armor
            EncryptionKey explicitSubkey = KerberosUtility.MakeKey(
                Context.SelectedEType,
                "Password04!",
                "This is a salt");
            Authenticator plaintextAuthenticator = CreateAuthenticator(Context.ArmorTicket, null, explicitSubkey);
            KerberosApRequest apReq = new KerberosApRequest(Context.Pvno,
                new APOptions(KerberosUtility.ConvertInt2Flags((int)apOptions)),
                Context.ArmorTicket,
                plaintextAuthenticator,
                KeyUsageNumber.AP_REQ_Authenticator);
            FastArmorApRequest explicitArmor = new FastArmorApRequest(apReq.Request);

            //Create armor key
            var armorKey = GetArmorKey(Context.ArmorSessionKey, subKey, explicitSubkey);
            Context.FastArmorkey = armorKey;

            //Create PA-FX-FAST
            var pafxfast = CreateTgsPaFxFast(armorKey, Context.ArmorTicket, fastOptions, apOptions, tempPaData, sName, paTgsReq.Data.padata_value.ByteArrayValue, explicitArmor);

            PA_DATA[] elements;
            if (outerSeqPaData != null && outerSeqPaData.Elements.Length > 0)
            {
                elements = new PA_DATA[outerSeqPaData.Elements.Length + 1];
                Array.Copy(outerSeqPaData.Elements, elements, outerSeqPaData.Elements.Length);
                elements[outerSeqPaData.Elements.Length] = pafxfast.Data;
                elements[outerSeqPaData.Elements.Length + 1] = paTgsReq.Data;
            }
            else
            {
                elements = new PA_DATA[] { pafxfast.Data, paTgsReq.Data };
            }
            Asn1SequenceOf<PA_DATA> seqPaData = new Asn1SequenceOf<PA_DATA>();
            KerberosTgsRequest tgsRequest = new KerberosTgsRequest(KerberosConstValue.KERBEROSV5, kdcReqBody, new Asn1SequenceOf<PA_DATA>(elements), Context.TransportType);

            this.SendPdu(tgsRequest);
            this.testSite.Log.Add(LogEntryKind.Debug, "Send FAST TGS request.");
        }
        /// <summary>
        /// Create and send FAST TGS request
        /// </summary>
        /// <param name="sName">Service principal name</param>
        /// <param name="kdcOptions">KDC options</param>
        /// <param name="innerSeqPaData">A sequence of preauthentication data in FAST request</param>
        /// <param name="outerSeqPaData">A sequence of preauthentication data</param>
        /// <param name="subKey">Sub-session key for authenticator in FAST armor field</param>
        /// <param name="fastOptions">FAST options</param>
        /// <param name="apOptions">AP options in FAST armor field</param>
        /// <param name="data">Authorization data</param>
        public void SendTgsRequestWithFastHideCName(
            string sName,
            PrincipalName cName,
            KdcOptions kdcOptions,
            Asn1SequenceOf<PA_DATA> innerSeqPaData,
            Asn1SequenceOf<PA_DATA> outerSeqPaData,
            EncryptionKey subKey,
            ApOptions apOptions,
            AuthorizationData data = null)
        {
            var fastOptions = new Protocols.TestTools.StackSdk.Security.KerberosV5.Preauth.FastOptions(
                KerberosUtility.ConvertInt2Flags((int)FastOptionFlags.Hide_Client_Names));
            Context.Subkey = subKey;
            Context.ReplyKey = subKey;
            string domain = this.Context.Realm.Value;
            PrincipalName sname = new PrincipalName(new KerbInt32((int)PrincipalType.NT_SRV_INST),
                KerberosUtility.String2SeqKerbString(sName.Split('/')));

            KDC_REQ_BODY kdcReqBody = CreateKdcRequestBody(kdcOptions, sname, data);
            kdcReqBody.cname = cName;
            Asn1BerEncodingBuffer bodyBuffer = new Asn1BerEncodingBuffer();
            kdcReqBody.BerEncode(bodyBuffer);

            APOptions option = new APOptions(KerberosUtility.ConvertInt2Flags((int)ApOptions.None));
            ChecksumType checksumType = KerberosUtility.GetChecksumType(Context.SelectedEType);
            KerberosApRequest apRequest = CreateApRequest(
                option,
                Context.Ticket,
                subKey,
                data,
                KeyUsageNumber.TG_REQ_PA_TGS_REQ_padataOR_AP_REQ_Authenticator,
                checksumType,
                bodyBuffer.Data);

            PaTgsReq paTgsReq = new PaTgsReq(apRequest.Request);

            Asn1SequenceOf<PA_DATA> tempPaData = null;
            if (outerSeqPaData == null || outerSeqPaData.Elements == null || outerSeqPaData.Elements.Length == 0)
            {
                tempPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paTgsReq.Data });
            }
            else
            {
                tempPaData.Elements = new PA_DATA[outerSeqPaData.Elements.Length + 1];
                Array.Copy(outerSeqPaData.Elements, tempPaData.Elements, outerSeqPaData.Elements.Length);
                tempPaData.Elements[outerSeqPaData.Elements.Length] = paTgsReq.Data;
            }
            var armorKey = GetArmorKey(Context.SessionKey, subKey);
            var pafxfast = CreateTgsPaFxFast(armorKey, Context.Ticket, fastOptions, apOptions, tempPaData, sName, paTgsReq.Data.padata_value.ByteArrayValue);
            Context.FastArmorkey = armorKey;
            PA_DATA[] elements;
            if (outerSeqPaData != null && outerSeqPaData.Elements.Length > 0)
            {
                elements = new PA_DATA[outerSeqPaData.Elements.Length + 1];
                Array.Copy(outerSeqPaData.Elements, elements, outerSeqPaData.Elements.Length);
                elements[outerSeqPaData.Elements.Length] = pafxfast.Data;
                elements[outerSeqPaData.Elements.Length + 1] = paTgsReq.Data;
            }
            else
            {
                elements = new PA_DATA[] { pafxfast.Data, paTgsReq.Data };
            }
            Asn1SequenceOf<PA_DATA> seqPaData = new Asn1SequenceOf<PA_DATA>();
            KerberosTgsRequest tgsRequest = new KerberosTgsRequest(KerberosConstValue.KERBEROSV5, kdcReqBody, new Asn1SequenceOf<PA_DATA>(elements), Context.TransportType);

            this.SendPdu(tgsRequest);
            this.testSite.Log.Add(LogEntryKind.Debug, "Send FAST TGS request.");
        }
 /// <summary>
 /// Create and send FAST AS request
 /// </summary>
 /// <param name="kdcOptions">KDC options</param>
 /// <param name="innerSeqPaData">A sequence of preauthentication data in FAST request</param>
 /// <param name="outerSeqPaData">A sequence of preauthentication data</param>
 /// <param name="subKey">Sub-session key for authenticator in FAST armor field</param>
 /// <param name="fastOptions">FAST options</param>
 /// <param name="apOptions">AP options in FAST armor field</param>
 public void SendAsRequestWithFastHideCName(
     KdcOptions kdcOptions,
     string cName,
     Asn1SequenceOf<PA_DATA> innerSeqPaData,
     Asn1SequenceOf<PA_DATA> outerSeqPaData,
     EncryptionKey subKey,
     ApOptions apOptions)
 {
     var fastOptions = new Protocols.TestTools.StackSdk.Security.KerberosV5.Preauth.FastOptions(
         KerberosUtility.ConvertInt2Flags((int)FastOptionFlags.Hide_Client_Names));
     Context.Subkey = subKey;
     string sName = KerberosConstValue.KERBEROS_SNAME;
     string domain = this.Context.Realm.Value;
     PrincipalName sname =
         new PrincipalName(new KerbInt32((int)PrincipalType.NT_SRV_INST), KerberosUtility.String2SeqKerbString(sName, domain));
     KDC_REQ_BODY kdcReqBody = CreateKdcRequestBody(kdcOptions, sname);
     kdcReqBody.cname = new PrincipalName(new KerbInt32((int)PrincipalType.NT_PRINCIPAL), KerberosUtility.String2SeqKerbString(cName));
     var pafxfast = CreateAsPaFxFast(subKey, fastOptions, apOptions, innerSeqPaData, sName, kdcReqBody);
     PA_DATA[] elements;
     if (outerSeqPaData != null && outerSeqPaData.Elements.Length > 0)
     {
         elements = new PA_DATA[outerSeqPaData.Elements.Length + 1];
         Array.Copy(outerSeqPaData.Elements, elements, outerSeqPaData.Elements.Length);
         elements[outerSeqPaData.Elements.Length] = pafxfast.Data;
     }
     else
     {
         elements = new PA_DATA[] { pafxfast.Data };
     }
     Asn1SequenceOf<PA_DATA> seqPaData = new Asn1SequenceOf<PA_DATA>();
     KerberosAsRequest asRequest = this.CreateAsRequest(kdcReqBody, new Asn1SequenceOf<PA_DATA>(elements));
     this.SendPdu(asRequest);
     this.testSite.Log.Add(LogEntryKind.Debug, "Send AS Request with FAST PA-DATA.");
 }
 /// <summary>
 /// Create and send FAST AS request with an unknown armor type
 /// </summary>
 /// <param name="kdcOptions">KDC options</param>
 /// <param name="innerSeqPaData">A sequence of preauthentication data in FAST request</param>
 /// <param name="outerSeqPaData">A sequence of preauthentication data</param>
 /// <param name="subKey">Sub-session key for authenticator in FAST armor field</param>
 /// <param name="fastOptions">FAST options</param>
 /// <param name="apOptions">AP options in FAST armor field</param>
 /// <param name="armorType">armorType</param>
 public void SendAsRequestWithFast(
     KdcOptions kdcOptions,
     Asn1SequenceOf<PA_DATA> innerSeqPaData,
     Asn1SequenceOf<PA_DATA> outerSeqPaData,
     EncryptionKey subKey,
     FastOptions fastOptions,
     ApOptions apOptions,
     KrbFastArmorType armorType
     )
 {
     Context.Subkey = subKey;
     string sName = KerberosConstValue.KERBEROS_SNAME;
     string domain = this.Context.Realm.Value;
     PrincipalName sname =
         new PrincipalName(new KerbInt32((int)PrincipalType.NT_SRV_INST), KerberosUtility.String2SeqKerbString(sName, domain));
     KDC_REQ_BODY kdcReqBody = CreateKdcRequestBody(kdcOptions, sname);
     var pafxfast = CreateAsPaFxFast(subKey, fastOptions, apOptions, innerSeqPaData, sName, kdcReqBody, armorType);
     PA_DATA[] elements;
     if (outerSeqPaData != null && outerSeqPaData.Elements.Length > 0)
     {
         elements = new PA_DATA[outerSeqPaData.Elements.Length + 1];
         Array.Copy(outerSeqPaData.Elements, elements, outerSeqPaData.Elements.Length);
         elements[outerSeqPaData.Elements.Length] = pafxfast.Data;
     }
     else
     {
         elements = new PA_DATA[] { pafxfast.Data };
     }
     Asn1SequenceOf<PA_DATA> seqPaData = new Asn1SequenceOf<PA_DATA>();
     KerberosAsRequest asRequest = this.CreateAsRequest(kdcReqBody, new Asn1SequenceOf<PA_DATA>(elements));
     this.SendPdu(asRequest);
     this.testSite.Log.Add(LogEntryKind.Debug, "Send AS Request with FAST PA-DATA.");
 }
        public PaFxFastReq CreateTgsPaFxFast(
            EncryptionKey armorKey,
            KerberosTicket armorTicket,
            FastOptions fastOptions,
            ApOptions apOptions,
            Asn1SequenceOf<PA_DATA> seqPaData,
            string sName,
            byte[] apReq,
            IFastArmor armor = null
            )
        {
            string domain = this.Context.Realm.Value;
            PrincipalName sname = new PrincipalName(new KerbInt32((int)PrincipalType.NT_SRV_INST),
                KerberosUtility.String2SeqKerbString(sName.Split('/')));

            KDC_REQ_BODY innerKdcReqBody = CreateKdcRequestBody(KdcOptions.CANONICALIZE | KdcOptions.FORWARDABLE | KdcOptions.RENEWABLE, sname);

            //Generate checksum
            var checksumType = KerberosUtility.GetChecksumType(Context.SelectedEType);
            var chksum = KerberosUtility.GetChecksum(
                armorKey.keyvalue.ByteArrayValue,
                apReq,
                (int)KeyUsageNumber.FAST_REQ_CHECKSUM,
                checksumType);
            Checksum checkSum = new Checksum(new KerbInt32((int)checksumType), new Asn1OctetString(chksum));

            KerberosFastRequest fastReq = new KerberosFastRequest(fastOptions, seqPaData, innerKdcReqBody);
            KerberosArmoredRequest armoredReq
                = new KerberosArmoredRequest(armor, checkSum, (long)Context.SelectedEType, armorKey.keyvalue.ByteArrayValue, fastReq);
            PA_FX_FAST_REQUEST paFxFastReq = new PA_FX_FAST_REQUEST();
            paFxFastReq.SetData(PA_FX_FAST_REQUEST.armored_data, armoredReq.FastArmoredReq);
            PaFxFastReq paFxfast = new PaFxFastReq(paFxFastReq);
            return paFxfast;
        }
        /// <summary>
        /// Create AP request and encode to GSSAPI token
        /// </summary>
        /// <param name="apOptions">AP options</param>
        /// <param name="data">Authorization data</param>
        /// <param name="subkey">Sub-session key in authenticator</param>
        /// <param name="checksumFlags">Checksum flags</param>
        /// <returns></returns>
        public byte[] CreateGssApiToken(ApOptions apOptions, AuthorizationData data, EncryptionKey subkey, ChecksumFlags checksumFlags,
            Microsoft.Protocols.TestTools.StackSdk.Security.KerberosLib.KerberosConstValue.GSSToken gssToken = KerberosConstValue.GSSToken.GSSSPNG)
        {
            APOptions options = new APOptions(KerberosUtility.ConvertInt2Flags((int)apOptions));

            Authenticator authenticator = CreateAuthenticator(Context.Ticket, data, subkey, checksumFlags);

            KerberosApRequest request = new KerberosApRequest(
                Context.Pvno,
                options,
                Context.Ticket,
                authenticator,
                KeyUsageNumber.AP_REQ_Authenticator
                );

            return KerberosUtility.AddGssApiTokenHeader(request, this.oidPkt, gssToken);
        }
        public PaFxFastReq CreateAsPaFxFast(
            EncryptionKey subKey,
            FastOptions fastOptions,
            ApOptions apOptions,
            Asn1SequenceOf<PA_DATA> seqPaData,
            string sName,
            KDC_REQ_BODY kdcReqBody,
            KrbFastArmorType armorType
            )
        {
            string domain = this.Context.Realm.Value;
            PrincipalName sname =
                new PrincipalName(new KerbInt32((int)PrincipalType.NT_SRV_INST), KerberosUtility.String2SeqKerbString(sName, domain));

            var armorKey = KerberosUtility.MakeArmorKey(
                Context.SelectedEType,
                subKey.keyvalue.ByteArrayValue,
                Context.ArmorSessionKey.keyvalue.ByteArrayValue);
            Context.FastArmorkey = new EncryptionKey(new KerbInt32((long)Context.SelectedEType), new Asn1OctetString(armorKey));

            Asn1BerEncodingBuffer encodebuf = new Asn1BerEncodingBuffer();
            kdcReqBody.BerEncode(encodebuf);
            var checksumType = KerberosUtility.GetChecksumType(Context.SelectedEType);
            var chksum = KerberosUtility.GetChecksum(
                armorKey,
                encodebuf.Data,
                (int)KeyUsageNumber.FAST_REQ_CHECKSUM,
                checksumType);
            Checksum checkSum = new Checksum(new KerbInt32((int)checksumType), new Asn1OctetString(chksum));

            Authenticator plaintextAuthenticator = CreateAuthenticator(Context.ArmorTicket, null, subKey);

            KerberosApRequest apReq = new KerberosApRequest(Context.Pvno,
                new APOptions(KerberosUtility.ConvertInt2Flags((int)apOptions)),
                Context.ArmorTicket,
                plaintextAuthenticator,
                KeyUsageNumber.AP_REQ_Authenticator);

            KDC_REQ_BODY innerKdcReqBody = CreateKdcRequestBody(KdcOptions.CANONICALIZE | KdcOptions.FORWARDABLE | KdcOptions.RENEWABLE, sname);
            KerberosFastRequest fastReq = new KerberosFastRequest(fastOptions, seqPaData, innerKdcReqBody);
            FastArmorApRequest fastArmor = new FastArmorApRequest(apReq.Request);
            fastArmor.armorType = armorType;
            KerberosArmoredRequest armoredReq
                = new KerberosArmoredRequest(fastArmor, checkSum, (long)Context.SelectedEType, armorKey, fastReq);
            PA_FX_FAST_REQUEST paFxFastReq = new PA_FX_FAST_REQUEST();
            paFxFastReq.SetData(PA_FX_FAST_REQUEST.armored_data, armoredReq.FastArmoredReq);
            PaFxFastReq paFxfast = new PaFxFastReq(paFxFastReq);
            return paFxfast;
        }