/// <summary> /// Updated context based on Kerberos pdu /// </summary> /// <param name="pdu">Kerberos pdu</param> public override void UpdateContext(KerberosPdu pdu) { if (pdu is KerberosAsRequest) { KerberosAsRequest request = (KerberosAsRequest)pdu; UpdateContext(request); } if (pdu is KerberosKrbError) { KerberosKrbError error = (KerberosKrbError)pdu; UpdateContext(error); } if (pdu is KerberosAsResponse) { KerberosAsResponse response = (KerberosAsResponse)pdu; UpdateContext(response); } if (pdu is KerberosTgsRequest) { KerberosTgsRequest request = pdu as KerberosTgsRequest; UpdateContext(request); } if (pdu is KerberosTgsResponse) { KerberosTgsResponse response = pdu as KerberosTgsResponse; UpdateContext(response); } this.expectedPduType = null; }
/// <summary> /// Expected a KDC_ERR_PREAUTH_REQUIRED error /// </summary> /// <param name="eData">Error data of this error</param> /// <returns></returns> private KerberosKrbError ExpectPreauthRequiredError(out METHOD_DATA eData) { KerberosPdu responsePdu = this.client.ExpectPdu(KerberosConstValue.TIMEOUT_DEFAULT, typeof(KerberosKrbError)); if ((responsePdu == null) || (!(responsePdu is KerberosKrbError))) { throw new InvalidOperationException("Response type should be KerberosKrbError"); } KerberosKrbError krbError = responsePdu as KerberosKrbError; if (!krbError.ErrorCode.Equals(KRB_ERROR_CODE.KDC_ERR_PREAUTH_REQUIRED)) { throw new InvalidOperationException("The Error code should be KDC_ERR_PREAUTH_REQUIRED"); } eData = new METHOD_DATA(); Asn1DecodingBuffer buffer = new Asn1DecodingBuffer(krbError.KrbError.e_data.ByteArrayValue); eData.BerDecode(buffer); return(krbError); }
private void UpdateContext(KerberosKrbError error) { switch (error.ErrorCode) { case KRB_ERROR_CODE.KDC_ERR_PREAUTH_REQUIRED: { var seqOfPadata = new Asn1SequenceOf <PA_DATA>(); seqOfPadata.BerDecode(new Asn1DecodingBuffer(error.KrbError.e_data.ByteArrayValue)); var padataCount = seqOfPadata.Elements.Length; for (int i = 0; i < padataCount; i++) { var padata = PaDataParser.ParseRepPaData(seqOfPadata.Elements[i]); //Fix me: PaETypeInfo is also possible if (padata is PaETypeInfo2) { var etypeinfo = padata as PaETypeInfo2; string salt; var etype = negotiateEtype(etypeinfo.ETypeInfo2.Elements, Context.SupportedEType.Elements, out salt); Context.SelectedEType = (EncryptionType)etype; if (!string.IsNullOrEmpty(salt)) { Context.CName.Salt = salt; } Context.ReplyKey = KerberosUtility.MakeKey(Context.SelectedEType, Context.CName.Password, Context.CName.Salt); } if (padata is PaFxFastRep) { //Fix me: Do something. } } break; } default: break; } }
private KerberosAsResponse ExpectAsResponse() { KerberosPdu responsePdu = this.client.ExpectPdu(KerberosConstValue.TIMEOUT_DEFAULT, typeof(KerberosAsResponse)); if (responsePdu == null) { throw new Exception("Expected KerberosAsResponse data is null"); } if (responsePdu is KerberosKrbError) { KerberosKrbError errorResponse = responsePdu as KerberosKrbError; throw new Exception($"Expected KerberosAsResponse failed, Error Code:{errorResponse.ErrorCode}"); } else if (!(responsePdu is KerberosAsResponse)) { throw new Exception($"Expected KerberosAsResponse failed, reponse type is not a valid KerberosAsResponse, Response Type:{responsePdu.GetType().ToString()}"); } KerberosAsResponse response = responsePdu as KerberosAsResponse; response.Decrypt(this.Context.ReplyKey.keyvalue.ByteArrayValue); return(response); }
public PaFxError(PA_DATA PaData) { paData = PaData; KrbError = new KerberosKrbError(); KrbError.FromBytes(PaData.padata_value.ByteArrayValue); }
//Get the expected Kerberos PDU from byte array private KerberosPdu getExpectedPduFromBytes( byte[] receivedBytes, out int consumedLength, out int expectedLength) { // initialize lengths consumedLength = 0; expectedLength = 0; if (null == receivedBytes || 0 == receivedBytes.Length) { return(null); } // TCP has a 4 bytes length header, while UDP has not byte[] pduBytes = receivedBytes; if ((this.Context.TransportType == TransportType.TCP)) { // insufficient data, needs to receive more if (receivedBytes.Length < sizeof(int)) { return(null); } // get pdu data length byte[] lengthBytes = ArrayUtility.SubArray(receivedBytes, 0, sizeof(int)); Array.Reverse(lengthBytes); int pduLength = BitConverter.ToInt32(lengthBytes, 0); // insufficient data, needs to receive more expectedLength = sizeof(int) + pduLength; if (receivedBytes.Length < expectedLength) { return(null); } // remove length header from pdu bytes pduBytes = ArrayUtility.SubArray <byte>(receivedBytes, sizeof(int), pduLength); } else { // UDP has no length header expectedLength = pduBytes.Length; } consumedLength = expectedLength; KerberosPdu pdu = null; //Get AP data in message to judge the kpassword type byte[] apLengthBytes = ArrayUtility.SubArray <byte>(pduBytes, 2 * sizeof(ushort), sizeof(ushort)); Array.Reverse(apLengthBytes); ushort apLength = BitConverter.ToUInt16(apLengthBytes, 0); //If the length is zero, then the last field contains a KRB-ERROR message instead of a KRB-PRIV message. if (apLength == 0) { pdu = new KerberosKrbError(); pdu.FromBytes(ArrayUtility.SubArray <byte>(pduBytes, 3 * sizeof(ushort))); return(pdu); } // get message type // (the lower 5 bits indicates its message type) byte[] apBytes = ArrayUtility.SubArray <byte>(pduBytes, 3 * sizeof(ushort), apLength); MsgType kpassMsgType = (MsgType)(apBytes[0] & 0x1f); if (kpassMsgType == MsgType.KRB_AP_REQ) { pdu = new KpasswordRequest(); } else { pdu = new KpasswordResponse(); pdu.FromBytes(pduBytes); } return(pdu); }
//Get the expected Kerberos PDU from byte array private KerberosPdu getExpectedPduFromBytes( byte[] receivedBytes, out int consumedLength, out int expectedLength) { // initialize lengths consumedLength = 0; expectedLength = 0; if (null == receivedBytes || 0 == receivedBytes.Length) { return(null); } // TCP has a 4 bytes length header, while UDP has not byte[] pduBytes = receivedBytes; if ((this.Context.TransportType == TransportType.TCP)) { // insufficient data, needs to receive more if (receivedBytes.Length < sizeof(int)) { return(null); } // get pdu data length byte[] lengthBytes = ArrayUtility.SubArray(receivedBytes, 0, sizeof(int)); Array.Reverse(lengthBytes); int pduLength = BitConverter.ToInt32(lengthBytes, 0); // insufficient data, needs to receive more expectedLength = sizeof(int) + pduLength; if (receivedBytes.Length < expectedLength) { return(null); } // remove length header from pdu bytes pduBytes = ArrayUtility.SubArray <byte>(receivedBytes, sizeof(int), pduLength); } else { // UDP has no length header expectedLength = pduBytes.Length; } // decode according to message type consumedLength = expectedLength; // get message type // (the lower 5 bits indicates its kile message type) MsgType kileMessageType = (MsgType)(pduBytes[0] & 0x1f); KerberosPdu pdu = null; switch (kileMessageType) { case MsgType.KRB_AS_REQ: pdu = new KerberosAsRequest(); break; case MsgType.KRB_AS_RESP: pdu = new KerberosAsResponse(); break; case MsgType.KRB_TGS_REQ: pdu = new KerberosTgsRequest(); break; case MsgType.KRB_TGS_RESP: pdu = new KerberosTgsResponse(); break; case MsgType.KRB_ERROR: pdu = new KerberosKrbError(); break; default: throw new FormatException( "Unsupported Message Type: " + kileMessageType.ToString()); } pdu.FromBytes(pduBytes); // update context if (this.expectedPduType == null || this.expectedPduType == pdu.GetType()) { this.UpdateContext(pdu); } return(pdu); }
public KerberosKrbError GetKrbErrorFromToken(byte[] token) { token = KerberosUtility.DecodeNegotiationToken(token); if (token[0] == KerberosConstValue.KERBEROS_TAG) { byte[] apData = KerberosUtility.VerifyGssApiTokenHeader(token, this.oidPkt); // Check if it has a two-byte tok_id if (null == apData || apData.Length <= sizeof(TOK_ID)) { throw new FormatException( "Data length is shorter than a valid AP Response data length."); } // verify TOK_ID byte[] tokenID = ArrayUtility.SubArray<byte>(apData, 0, sizeof(TOK_ID)); Array.Reverse(tokenID); TOK_ID id = (TOK_ID)BitConverter.ToUInt16(tokenID, 0); this.testSite.Assert.AreEqual(TOK_ID.KRB_ERROR, id, "The Token ID should be KRB_ERROR"); // Get apBody token = ArrayUtility.SubArray(apData, sizeof(TOK_ID)); } KerberosKrbError error = new KerberosKrbError(); error.FromBytes(token); return error; }
private void UpdateContext(KerberosKrbError error) { switch (error.ErrorCode) { case KRB_ERROR_CODE.KDC_ERR_PREAUTH_REQUIRED: { var seqOfPadata = new Asn1SequenceOf<PA_DATA>(); seqOfPadata.BerDecode(new Asn1DecodingBuffer(error.KrbError.e_data.ByteArrayValue)); var padataCount = seqOfPadata.Elements.Length; for (int i = 0; i < padataCount; i++) { var padata = PaDataParser.ParseRepPaData(seqOfPadata.Elements[i]); //Fix me: PaETypeInfo is also possible if (padata is PaETypeInfo2) { var etypeinfo = padata as PaETypeInfo2; string salt; var etype = negotiateEtype(etypeinfo.ETypeInfo2.Elements, Context.SupportedEType.Elements, out salt); Context.SelectedEType = (EncryptionType)etype; if (!string.IsNullOrEmpty(salt)) Context.CName.Salt = salt; Context.ReplyKey = KerberosUtility.MakeKey(Context.SelectedEType, Context.CName.Password, Context.CName.Salt); } if (padata is PaFxFastRep) { //Fix me: Do something. } } break; } default: break; } }
//Get the expected Kerberos PDU from byte array private KerberosPdu getExpectedPduFromBytes( byte[] receivedBytes, out int consumedLength, out int expectedLength) { // initialize lengths consumedLength = 0; expectedLength = 0; if (null == receivedBytes || 0 == receivedBytes.Length) { return null; } // TCP has a 4 bytes length header, while UDP has not byte[] pduBytes = receivedBytes; if ((this.Context.TransportType == TransportType.TCP)) { // insufficient data, needs to receive more if (receivedBytes.Length < sizeof(int)) { return null; } // get pdu data length byte[] lengthBytes = ArrayUtility.SubArray(receivedBytes, 0, sizeof(int)); Array.Reverse(lengthBytes); int pduLength = BitConverter.ToInt32(lengthBytes, 0); // insufficient data, needs to receive more expectedLength = sizeof(int) + pduLength; if (receivedBytes.Length < expectedLength) { return null; } // remove length header from pdu bytes pduBytes = ArrayUtility.SubArray<byte>(receivedBytes, sizeof(int), pduLength); } else { // UDP has no length header expectedLength = pduBytes.Length; } // decode according to message type consumedLength = expectedLength; // get message type // (the lower 5 bits indicates its kile message type) MsgType kileMessageType = (MsgType)(pduBytes[0] & 0x1f); KerberosPdu pdu = null; switch (kileMessageType) { case MsgType.KRB_AS_REQ: pdu = new KerberosAsRequest(); break; case MsgType.KRB_AS_RESP: pdu = new KerberosAsResponse(); break; case MsgType.KRB_TGS_REQ: pdu = new KerberosTgsRequest(); break; case MsgType.KRB_TGS_RESP: pdu = new KerberosTgsResponse(); break; case MsgType.KRB_ERROR: pdu = new KerberosKrbError(); break; default: throw new FormatException( "Unsupported Message Type: " + kileMessageType.ToString()); } pdu.FromBytes(pduBytes); // update context if (this.expectedPduType == null || this.expectedPduType == pdu.GetType()) this.UpdateContext(pdu); return pdu; }
//Get the expected Kerberos PDU from byte array private KerberosPdu getExpectedPduFromBytes( byte[] receivedBytes, out int consumedLength, out int expectedLength) { // initialize lengths consumedLength = 0; expectedLength = 0; if (null == receivedBytes || 0 == receivedBytes.Length) { return null; } // TCP has a 4 bytes length header, while UDP has not byte[] pduBytes = receivedBytes; if ((this.Context.TransportType == TransportType.TCP)) { // insufficient data, needs to receive more if (receivedBytes.Length < sizeof(int)) { return null; } // get pdu data length byte[] lengthBytes = ArrayUtility.SubArray(receivedBytes, 0, sizeof(int)); Array.Reverse(lengthBytes); int pduLength = BitConverter.ToInt32(lengthBytes, 0); // insufficient data, needs to receive more expectedLength = sizeof(int) + pduLength; if (receivedBytes.Length < expectedLength) { return null; } // remove length header from pdu bytes pduBytes = ArrayUtility.SubArray<byte>(receivedBytes, sizeof(int), pduLength); } else { // UDP has no length header expectedLength = pduBytes.Length; } consumedLength = expectedLength; KerberosPdu pdu = null; //Get AP data in message to judge the kpassword type byte[] apLengthBytes = ArrayUtility.SubArray<byte>(pduBytes, 2 * sizeof(ushort), sizeof(ushort)); Array.Reverse(apLengthBytes); ushort apLength = BitConverter.ToUInt16(apLengthBytes, 0); //If the length is zero, then the last field contains a KRB-ERROR message instead of a KRB-PRIV message. if (apLength == 0) { pdu = new KerberosKrbError(); pdu.FromBytes(ArrayUtility.SubArray<byte>(pduBytes, 3 * sizeof(ushort))); return pdu; } // get message type // (the lower 5 bits indicates its message type) byte[] apBytes = ArrayUtility.SubArray<byte>(pduBytes, 3 * sizeof(ushort), apLength); MsgType kpassMsgType = (MsgType)(apBytes[0] & 0x1f); if (kpassMsgType == MsgType.KRB_AP_REQ) { pdu = new KpasswordRequest(); } else { pdu = new KpasswordResponse(); pdu.FromBytes(pduBytes); } return pdu; }