/// <summary>
        /// Construct a Kerberos test client for FAST
        /// </summary>
        /// <param name="domain">The realm part of the client's principal identifier.
        /// This argument cannot be null.</param>
        /// <param name="cName">The account to logon the remote machine. Either user account or computer account
        /// This argument cannot be null.</param>
        /// <param name="password">The password of the user. This argument cannot be null.</param>
        /// <param name="accountType">The type of the logon account. User or Computer</param>
        public KerberosFunctionalClient(string domain, string cName, string password, KerberosAccountType accountType, KerberosTicket armorTicket, EncryptionKey armorSessionKey, string kdcAddress, int kdcPort, TransportType transportType, KerberosConstValue.OidPkt omiPkt, ITestSite baseTestSite)
            : base(domain, cName, password, accountType, armorTicket, armorSessionKey, kdcAddress, kdcPort, transportType, omiPkt)
        {
            testSite = baseTestSite;
            if (accountType == KerberosAccountType.Device)
            {
                testSite.Log.Add(LogEntryKind.Debug, "Construct Kerberos client using computer account: {0}@{1}.",
                                    cName, domain);
            }
            else
            {
                testSite.Log.Add(LogEntryKind.Debug, "Construct Kerberos client using user account: {0}@{1}.",
                                    cName, domain);
            }
            EncryptionType[] encryptionTypes = new EncryptionType[]
            {
                EncryptionType.AES256_CTS_HMAC_SHA1_96,
                EncryptionType.AES128_CTS_HMAC_SHA1_96,
                EncryptionType.RC4_HMAC,
                EncryptionType.RC4_HMAC_EXP,
                EncryptionType.DES_CBC_CRC,
                EncryptionType.DES_CBC_MD5
            };

            KerbInt32[] etypes = new KerbInt32[encryptionTypes.Length];
            for (int i = 0; i < encryptionTypes.Length; i++)
            {
                etypes[i] = new KerbInt32((int)encryptionTypes[i]);
            }
            Asn1SequenceOf<KerbInt32> etype = new Asn1SequenceOf<KerbInt32>(etypes);

            Context.SupportedEType = etype;

            Context.Pvno = KerberosConstValue.KERBEROSV5;
        }
 /// <summary>
 /// Create context
 /// </summary>
 /// <param name="domain">Domain name</param>
 /// <param name="cName">Principal name</param>
 /// <param name="password">Password of principal</param>
 /// <param name="accountType">Accoundtype, user or device</param>
 /// <param name="armorTicket">Computer TGT as armor ticket</param>
 /// <param name="armorSessionKey">Computer TGS session key as armor session key</param>
 public KerberosContext(string domain, string cName, string password, KerberosAccountType accountType, string salt, KerberosTicket armorTicket, EncryptionKey armorSessionKey)
     : this(domain, cName, password, accountType, salt)
 {
     this.ArmorTicket = armorTicket;
     this.ArmorSessionKey = armorSessionKey;
     this.SelectedEType = (EncryptionType)this.ArmorTicket.SessionKey.keytype.Value;
 }
 /// <summary>
 /// Create a KileClient instance.
 /// </summary>
 /// <param name="domain">The realm part of the client's principal identifier.
 /// This argument cannot be null.</param>
 /// <param name="cName">The account to logon the remote machine. Either user account or computer account
 /// This argument cannot be null.</param>
 /// <param name="password">The password of the user. This argument cannot be null.</param>
 /// <param name="accountType">The type of the logon account. User or Computer</param>
 /// <param name="kdcAddress">The IP address of the KDC.</param>
 /// <param name="kdcPort">The port of the KDC.</param>
 /// <param name="transportType">Whether the transport is TCP or UDP transport.</param>
 /// <exception cref="System.ArgumentNullException">Thrown when the input parameter is null.</exception>
 public KerberosClient(string domain, string cName, string password, KerberosAccountType accountType, KerberosTicket armorTicket, EncryptionKey armorSessionKey, string kdcAddress, int kdcPort, TransportType transportType, KerberosConstValue.OidPkt oidPkt = KerberosConstValue.OidPkt.KerberosToken, string salt = null)
 {
     TransportBufferSize = KerberosConstValue.TRANSPORT_BUFFER_SIZE;
     this.Context = new KerberosContext(domain, cName, password, accountType, salt, armorTicket, armorSessionKey);
     this.kdcAddress = kdcAddress;
     this.kdcPort = kdcPort;
     this.transportType = transportType;
     this.oidPkt = oidPkt;
     this.Context.TransportType = transportType;
 }
        /// <summary>
        /// Create an instance.
        /// </summary>
        public KpasswordRequest(KerberosTicket ticket, Authenticator authenticator, string newPwd, bool isAuthErrorRequired = false)
        {
            //Create KerberosApRequest
            long pvno = KerberosConstValue.KERBEROSV5;
            APOptions option = new APOptions(KerberosUtility.ConvertInt2Flags((int)ApOptions.None));
            KerberosApRequest ap_req = new KerberosApRequest(pvno, option, ticket, authenticator, KeyUsageNumber.AP_REQ_Authenticator);
            //Create KRB_PRIV
            ChangePasswdData pwd_data = new ChangePasswdData(new Asn1OctetString(newPwd), null, null);
            priv_enc_part = new EncKrbPrivPart();
            priv_enc_part.user_data = pwd_data.newpasswd;
            priv_enc_part.usec = authenticator.cusec;
            priv_enc_part.seq_number = authenticator.seq_number;
            priv_enc_part.s_address = new HostAddress(new KerbInt32((int)AddressType.NetBios), new Asn1OctetString(Encoding.ASCII.GetBytes(System.Net.Dns.GetHostName())));
            Asn1BerEncodingBuffer asnBuffPriv = new Asn1BerEncodingBuffer();
            priv_enc_part.BerEncode(asnBuffPriv, true);
            byte[] encAsnEncodedPriv = null;

            if (!isAuthErrorRequired)
            {
                encAsnEncodedPriv = KerberosUtility.Encrypt((EncryptionType)authenticator.subkey.keytype.Value,
                            authenticator.subkey.keyvalue.ByteArrayValue,
                            asnBuffPriv.Data,
                            (int)KeyUsageNumber.KRB_PRIV_EncPart);
            }
            else
            {
                encAsnEncodedPriv = KerberosUtility.Encrypt((EncryptionType)authenticator.subkey.keytype.Value,
                            authenticator.subkey.keyvalue.ByteArrayValue,
                            asnBuffPriv.Data,
                            (int)KeyUsageNumber.None);
            }

            var encrypted = new EncryptedData();
            encrypted.etype = new KerbInt32(authenticator.subkey.keytype.Value);
            encrypted.cipher = new Asn1OctetString(encAsnEncodedPriv);
            KRB_PRIV krb_priv = new KRB_PRIV(new Asn1Integer(pvno), new Asn1Integer((long)MsgType.KRB_PRIV), encrypted);
            //Calculate the msg_length and ap_req_length
            krb_priv.BerEncode(privBuffer, true);
            ap_req.Request.BerEncode(apBuffer, true);
            version = 0x0001;
            ap_req_length = (ushort)apBuffer.Data.Length;
            msg_length = (ushort)(ap_req_length + privBuffer.Data.Length + 3 * sizeof(ushort));
            //Convert Endian
            version = KerberosUtility.ConvertEndian(version);
            ap_req_length = KerberosUtility.ConvertEndian(ap_req_length);
            msg_length = KerberosUtility.ConvertEndian(msg_length);
        }
        /// <summary>
        /// Create an instance.
        /// </summary>
        public KerberosApRequest(long pvno, APOptions ap_options, KerberosTicket ticket, Authenticator authenticator, KeyUsageNumber keyUsageNumber)
        {
            Asn1BerEncodingBuffer asnBuffPlainAuthenticator = new Asn1BerEncodingBuffer();
            authenticator.BerEncode(asnBuffPlainAuthenticator, true);
            KerberosUtility.OnDumpMessage("KRB5:Authenticator",
                "Authenticator in AP-REQ structure",
                 KerberosUtility.DumpLevel.PartialMessage,
                 asnBuffPlainAuthenticator.Data);
            byte[] encAsnEncodedAuth = KerberosUtility.Encrypt((EncryptionType)ticket.SessionKey.keytype.Value,
                                    ticket.SessionKey.keyvalue.ByteArrayValue,
                                    asnBuffPlainAuthenticator.Data,
                                    (int)keyUsageNumber);
            var encrypted = new EncryptedData();
            encrypted.etype = new KerbInt32(ticket.SessionKey.keytype.Value);
            encrypted.cipher = new Asn1OctetString(encAsnEncodedAuth);

            long msg_type = (long)MsgType.KRB_AP_REQ;
            Request = new AP_REQ(new Asn1Integer(pvno), new Asn1Integer(msg_type), ap_options, ticket.Ticket, encrypted);
            Authenticator = authenticator;
        }
        private Authenticator CreateAuthenticator(
            KerberosTicket ticket,
            AuthorizationData data,
            EncryptionKey subkey,
            ChecksumType checksumType,
            byte[] checksumBody
            )
        {
            Authenticator plaintextAuthenticator = CreateAuthenticator(ticket, data, subkey);

            byte[] checkData = KerberosUtility.GetChecksum(ticket.SessionKey.keyvalue.ByteArrayValue,
                checksumBody, (int)KeyUsageNumber.TGS_REQ_PA_TGS_REQ_adataOR_AP_REQ_Authenticator_cksum, checksumType);

            plaintextAuthenticator.cksum = new Checksum(new KerbInt32((int)checksumType), new Asn1OctetString(checkData));
            return plaintextAuthenticator;
        }
 private Authenticator CreateAuthenticator(
     KerberosTicket ticket,
     AuthorizationData data,
     EncryptionKey subkey
     )
 {
     Authenticator plaintextAuthenticator = new Authenticator();
     plaintextAuthenticator.authenticator_vno = new Asn1Integer(KerberosConstValue.KERBEROSV5);
     plaintextAuthenticator.crealm = Context.CName.Realm;
     plaintextAuthenticator.cusec = new Microseconds(0);
     plaintextAuthenticator.ctime = KerberosUtility.CurrentKerberosTime;
     plaintextAuthenticator.seq_number = new KerbUInt32(0);
     plaintextAuthenticator.cname = ticket.TicketOwner;
     plaintextAuthenticator.subkey = subkey;
     plaintextAuthenticator.authorization_data = data;
     return plaintextAuthenticator;
 }
 private KerberosApRequest CreateApRequest(APOptions option, KerberosTicket ticket, EncryptionKey subkey, AuthorizationData data, KeyUsageNumber keyUsageNumber, ChecksumType checksumType, byte[] checksumBody)
 {
     Authenticator authenticator = CreateAuthenticator(ticket, data, subkey, checksumType, checksumBody);
     KerberosApRequest apReq = new KerberosApRequest(Context.Pvno, option, ticket, authenticator, keyUsageNumber);
     return apReq;
 }
        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 authenticator for ChecksumType.ap_authenticator_8003
        /// </summary>
        private Authenticator CreateAuthenticator(
            KerberosTicket ticket,
            AuthorizationData data,
            EncryptionKey subkey,
            ChecksumFlags checksumFlag
            )
        {
            Authenticator plaintextAuthenticator = CreateAuthenticator(ticket, data, subkey);

            AuthCheckSum checksum = new AuthCheckSum();
            checksum.Lgth = KerberosConstValue.AUTHENTICATOR_CHECKSUM_LENGTH;
            checksum.Bnd = new byte[checksum.Lgth];
            checksum.Flags = (int)checksumFlag;
            byte[] checkData = ArrayUtility.ConcatenateArrays(BitConverter.GetBytes(checksum.Lgth),
                checksum.Bnd, BitConverter.GetBytes(checksum.Flags));

            plaintextAuthenticator.cksum = new Checksum(new KerbInt32((int)ChecksumType.ap_authenticator_8003), new Asn1OctetString(checkData));
            return plaintextAuthenticator;
        }
 /// <summary>
 /// Construct a kpassword test client
 /// </summary>
 /// <param name="kdcAddress">The IP address of the KDC.</param>
 /// <param name="kdcPort">The port of the KDC for Kpassword.</param>
 /// <param name="transportType">Whether the transport is TCP or UDP transport.</param>
 /// <param name="ticket">The ticket authorized to change password</param>
 public KpasswdTestClient(string kdcAddress, int kdcPort, TransportType transportType, KerberosTicket ticket)
     : base(kdcAddress, kdcPort, transportType)
 {
     testSite = TestClassBase.BaseTestSite;
     this.Context.Ticket = ticket;
 }