/// <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); } } }