Ejemplo n.º 1
0
        /// <summary>
        /// Update the context.
        /// </summary>
        /// <param name="pdu">The PDU to update the context.</param>
        internal override void UpdateContext(KilePdu pdu)
        {
            if (pdu == null)
            {
                return;
            }

            lock (contextLock)
            {
                Type pduType = pdu.GetType();

                if (pduType == typeof(KileAsRequest))
                {
                    KileAsRequest request = (KileAsRequest)pdu;
                    if (request.Request != null && request.Request.req_body != null)
                    {
                        cName  = request.Request.req_body.cname;
                        cRealm = request.Request.req_body.realm;
                        eType  = request.Request.req_body.etype;
                    }
                }
                else if (pduType == typeof(KileAsResponse))
                {
                    KileAsResponse response = (KileAsResponse)pdu;
                    if (response.EncPart != null)
                    {
                        tgsSessionKey = response.EncPart.key;
                    }

                    if (response.Response != null)
                    {
                        tgsTicket = response.Response.ticket;
                        if (tgsTicket != null && tgsTicket.sname != null &&
                            tgsTicket.sname.name_string != null && tgsTicket.sname.name_string.Elements != null &&
                            tgsTicket.sname.name_string.Elements.Length > 1)
                        {
                            int count = tgsTicket.sname.name_string.Elements.Length;
                            cRealm = new Realm(tgsTicket.sname.name_string.Elements[count - 1].Value);
                        }

                        if (response.Response.padata != null && response.Response.padata.Elements != null)
                        {
                            foreach (PA_DATA paData in response.Response.padata.Elements)
                            {
                                if (paData.padata_type != null &&
                                    paData.padata_type.Value == (long)PaDataType.PA_ETYPE_INFO2)
                                {
                                    Asn1DecodingBuffer buffer     = new Asn1DecodingBuffer(paData.padata_value.ByteArrayValue);
                                    ETYPE_INFO2        eTypeInfo2 = new ETYPE_INFO2();
                                    eTypeInfo2.BerDecode(buffer);
                                    if (eTypeInfo2.Elements != null && eTypeInfo2.Elements.Length > 0)
                                    {
                                        // the salt is received from KDC
                                        salt = eTypeInfo2.Elements[0].salt.Value;
                                        return;
                                    }
                                }
                            }
                        }
                    }
                }
                else if (pduType == typeof(KileTgsResponse))
                {
                    KileTgsResponse response = (KileTgsResponse)pdu;
                    if (response.Response != null)
                    {
                        apTicket = response.Response.ticket;
                        if (apTicket != null && apTicket.sname != null &&
                            apTicket.sname.name_string != null && apTicket.sname.name_string.Elements != null &&
                            apTicket.sname.name_string.Elements.Length > 1)
                        {
                            int count = apTicket.sname.name_string.Elements.Length;
                            cRealm = new Realm(apTicket.sname.name_string.Elements[count - 1].Value);
                        }
                    }

                    if (response.EncPart != null)
                    {
                        apSessionKey = response.EncPart.key;
                    }
                }
                else if (pduType == typeof(KileApRequest))
                {
                    KileApRequest request = (KileApRequest)pdu;
                    if (request.Authenticator != null)
                    {
                        apSubKey       = request.Authenticator.subkey;
                        apRequestCtime = request.Authenticator.ctime;
                        apRequestCusec = request.Authenticator.cusec;

                        if (request.Authenticator.cksum != null &&
                            request.Authenticator.cksum.cksumtype.Value == (int)ChecksumType.ap_authenticator_8003 &&
                            request.Authenticator.cksum.checksum != null &&
                            request.Authenticator.cksum.checksum.Value != null &&
                            request.Authenticator.cksum.checksum.Value.Length == ConstValue.AUTH_CHECKSUM_SIZE)
                        {
                            int flag = BitConverter.ToInt32(request.Authenticator.cksum.checksum.ByteArrayValue,
                                                            ConstValue.AUTHENTICATOR_CHECKSUM_LENGTH + sizeof(int));
                            checksumFlag = (ChecksumFlags)flag;
                        }

                        if (request.Authenticator.seq_number != null)
                        {
                            currentLocalSequenceNumber  = (ulong)request.Authenticator.seq_number.Value;
                            currentRemoteSequenceNumber = currentLocalSequenceNumber;
                        }
                    }
                }
                else if (pduType == typeof(KileApResponse))
                {
                    KileApResponse response = (KileApResponse)pdu;
                    if (response.ApEncPart != null)
                    {
                        if (response.ApEncPart.seq_number != null)
                        {
                            currentRemoteSequenceNumber = (ulong)response.ApEncPart.seq_number.Value;
                        }

                        if (response.ApEncPart.subkey != null)
                        {
                            acceptorSubKey = response.ApEncPart.subkey;
                        }
                    }
                }
                // else do nothing
            }
        }
 public PaETypeInfo2(ETYPE_INFO2 eTypeInfo2)
 {
     ETypeInfo2 = eTypeInfo2;
 }
 /// <summary>
 /// Parse raw PA_DATA type to PaFxFast object.
 /// </summary>
 /// <param name="data">Raw PA_DATA</param>
 /// <returns>Reference to PaFxFast object</returns>
 public static PaETypeInfo2 Parse(PA_DATA data)
 {
     if (data.padata_type.Value != (long)PaDataType.PA_ETYPE_INFO2)
         throw new Exception();
     ETYPE_INFO2 eTypeInfo = new ETYPE_INFO2();
     eTypeInfo.BerDecode(new Asn1DecodingBuffer(data.padata_value.ByteArrayValue));
     return new PaETypeInfo2(eTypeInfo);
 }
        private void UpdateContext(KerberosAsResponse response)
        {
            KerberosFastResponse kerbFastRep = null;
            if (response.Response.padata != null && response.Response.padata.Elements != null)
            {
                foreach (PA_DATA paData in response.Response.padata.Elements)
                {
                    var parsedPaData = PaDataParser.ParseRepPaData(paData);
                    if (parsedPaData is PaETypeInfo2)
                    {
                        Asn1DecodingBuffer buffer = new Asn1DecodingBuffer(paData.padata_value.ByteArrayValue);
                        ETYPE_INFO2 eTypeInfo2 = new ETYPE_INFO2();
                        eTypeInfo2.BerDecode(buffer);
                        if (eTypeInfo2.Elements != null && eTypeInfo2.Elements.Length > 0)
                        {
                            // the salt is received from KDC
                            if (eTypeInfo2.Elements[0].salt != null)
                                Context.CName.Salt = eTypeInfo2.Elements[0].salt.Value;
                            continue;
                        }
                    }
                    if (parsedPaData is PaFxFastRep)
                    {
                        var armoredRep = ((PaFxFastRep)parsedPaData).GetArmoredRep();
                        kerbFastRep = ((PaFxFastRep)parsedPaData).GetKerberosFastRep(Context.FastArmorkey);
                        var strKey = kerbFastRep.FastResponse.strengthen_key;
                        Context.ReplyKey = KerberosUtility.KrbFxCf2(
                            strKey,
                            //Fix me: should be Context.ReplyKey
                            KerberosUtility.MakeKey(Context.SelectedEType, Context.CName.Password, Context.CName.Salt),
                            "strengthenkey",
                            "replykey");
                    }
                }
            }

            if (Context.ReplyKey != null)
            {
                response.Decrypt(Context.ReplyKey.keyvalue.ByteArrayValue);
            }
            else
            {
                var encryptType = (EncryptionType)response.Response.enc_part.etype.Value;
                var key = KeyGenerator.MakeKey(encryptType, Context.CName.Password, Context.CName.Salt);
                Context.ReplyKey = new EncryptionKey(new KerbInt32((long)encryptType), new Asn1OctetString(key));
                response.Decrypt(key);
            }

            if (response.EncPart != null)
            {
                Context.SessionKey = response.EncPart.key;
            }

            if (response.Response != null)
            {
                //Response.Response.cname is not the real CName of the ticket when hide-client-names=1
                if (kerbFastRep != null && kerbFastRep.FastResponse != null && kerbFastRep.FastResponse.finished != null)
                {
                    // Windows DC is case insensitive. It may change the cname in the response, e.g. administrator -> Administrator
                    Context.CName.Name = kerbFastRep.FastResponse.finished.cname;
                    Context.Ticket = new KerberosTicket(response.Response.ticket, kerbFastRep.FastResponse.finished.cname, response.EncPart.key);
                }
                else
                {
                    // Windows DC is case insensitive. It may change the cname in the response, e.g. administrator -> Administrator
                    Context.CName.Name = response.Response.cname;
                    Context.Ticket = new KerberosTicket(response.Response.ticket, response.Response.cname, response.EncPart.key);
                }
                Context.SelectedEType = (EncryptionType)Context.Ticket.SessionKey.keytype.Value;
                if (Context.Ticket != null && Context.Ticket.Ticket.sname != null
                    && Context.Ticket.Ticket.sname.name_string != null
                    && Context.Ticket.Ticket.sname.name_string.Elements != null
                    && Context.Ticket.Ticket.sname.name_string.Elements.Length > 1)
                {
                    int count = Context.Ticket.Ticket.sname.name_string.Elements.Length;
                    Context.Realm = new Realm(Context.Ticket.Ticket.sname.name_string.Elements[count - 1].Value);
                }
            }
        }