private static List <byte[]> ReadMechanismTypeList(byte[] buffer, ref int offset) { List <byte[]> result = new List <byte[]>(); int constructionLength = DerEncodingHelper.ReadLength(buffer, ref offset); byte tag = ByteReader.ReadByte(buffer, ref offset); if (tag != (byte)DerEncodingTag.Sequence) { throw new InvalidDataException(); } int sequenceLength = DerEncodingHelper.ReadLength(buffer, ref offset); int sequenceEndOffset = offset + sequenceLength; while (offset < sequenceEndOffset) { tag = ByteReader.ReadByte(buffer, ref offset); if (tag != (byte)DerEncodingTag.ObjectIdentifier) { throw new InvalidDataException(); } int mechanismTypeLength = DerEncodingHelper.ReadLength(buffer, ref offset); byte[] mechanismType = ByteReader.ReadBytes(buffer, ref offset, mechanismTypeLength); result.Add(mechanismType); } return(result); }
protected static string ReadHints(byte[] buffer, ref int offset, out byte[] hintAddress) { string hintName = null; hintAddress = null; int constructionLength = DerEncodingHelper.ReadLength(buffer, ref offset); byte tag = ByteReader.ReadByte(buffer, ref offset); if (tag != (byte)DerEncodingTag.Sequence) { throw new InvalidDataException(); } int sequenceLength = DerEncodingHelper.ReadLength(buffer, ref offset); int sequenceEndOffset = offset + sequenceLength; while (offset < sequenceEndOffset) { tag = ByteReader.ReadByte(buffer, ref offset); if (tag == HintNameTag) { hintName = ReadHintName(buffer, ref offset); } else if (tag == HintAddressTag) { hintAddress = ReadHintAddress(buffer, ref offset); } else { throw new InvalidDataException(); } } return(hintName); }
/// <summary> /// https://tools.ietf.org/html/rfc2743 /// </summary> public static SimpleProtectedNegotiationToken ReadToken(byte[] tokenBytes, int offset) { byte tag = ByteReader.ReadByte(tokenBytes, ref offset); if (tag == ApplicationTag) { // when an InitToken is sent, it is prepended by an Application Constructed Object specifier (0x60), // and the OID for SPNEGO (see value in OID table above). This is the generic GSSAPI header. int tokenLength = DerEncodingHelper.ReadLength(tokenBytes, ref offset); tag = ByteReader.ReadByte(tokenBytes, ref offset); if (tag == (byte)DerEncodingTag.ObjectIdentifier) { int objectIdentifierLength = DerEncodingHelper.ReadLength(tokenBytes, ref offset); byte[] objectIdentifier = ByteReader.ReadBytes(tokenBytes, ref offset, objectIdentifierLength); if (ByteUtils.AreByteArraysEqual(objectIdentifier, SPNEGOIdentifier)) { tag = ByteReader.ReadByte(tokenBytes, ref offset); if (tag == SimpleProtectedNegotiationTokenInit.NegTokenInitTag) { return(new SimpleProtectedNegotiationTokenInit(tokenBytes, offset)); } } } } else if (tag == SimpleProtectedNegotiationTokenResponse.NegTokenRespTag) { return(new SimpleProtectedNegotiationTokenResponse(tokenBytes, offset)); } return(null); }
private static NegState ReadNegState(byte[] buffer, ref int offset) { int length = DerEncodingHelper.ReadLength(buffer, ref offset); byte tag = ByteReader.ReadByte(buffer, ref offset); if (tag != (byte)DerEncodingTag.Enum) { throw new InvalidDataException(); } length = DerEncodingHelper.ReadLength(buffer, ref offset); return((NegState)ByteReader.ReadByte(buffer, ref offset)); }
private static byte[] ReadMechanismListMIC(byte[] buffer, ref int offset) { int constructionLength = DerEncodingHelper.ReadLength(buffer, ref offset); byte tag = ByteReader.ReadByte(buffer, ref offset); if (tag != (byte)DerEncodingTag.ByteArray) { throw new InvalidDataException(); } int length = DerEncodingHelper.ReadLength(buffer, ref offset); return(ByteReader.ReadBytes(buffer, ref offset, length)); }
private static byte[] ReadSupportedMechanism(byte[] buffer, ref int offset) { int constructionLength = DerEncodingHelper.ReadLength(buffer, ref offset); byte tag = ByteReader.ReadByte(buffer, ref offset); if (tag != (byte)DerEncodingTag.ObjectIdentifier) { throw new InvalidDataException(); } int length = DerEncodingHelper.ReadLength(buffer, ref offset); return(ByteReader.ReadBytes(buffer, ref offset, length)); }
protected static byte[] ReadHintAddress(byte[] buffer, ref int offset) { int constructionLength = DerEncodingHelper.ReadLength(buffer, ref offset); byte tag = ByteReader.ReadByte(buffer, ref offset); if (tag != (byte)DerEncodingTag.ByteArray) { throw new InvalidDataException(); } int hintLength = DerEncodingHelper.ReadLength(buffer, ref offset); return(ByteReader.ReadBytes(buffer, ref offset, hintLength)); }
protected static byte[] ReadMechanismToken(byte[] buffer, ref int offset) { int constructionLength = DerEncodingHelper.ReadLength(buffer, ref offset); byte tag = ByteReader.ReadByte(buffer, ref offset); if (tag != (byte)DerEncodingTag.ByteArray) { throw new InvalidDataException(); } int mechanismTokenLength = DerEncodingHelper.ReadLength(buffer, ref offset); byte[] token = ByteReader.ReadBytes(buffer, ref offset, mechanismTokenLength); return(token); }
protected static string ReadHintName(byte[] buffer, ref int offset) { int constructionLength = DerEncodingHelper.ReadLength(buffer, ref offset); byte tag = ByteReader.ReadByte(buffer, ref offset); if (tag != (byte)DerEncodingTag.GeneralString) { throw new InvalidDataException(); } int hintLength = DerEncodingHelper.ReadLength(buffer, ref offset); byte[] hintNameBytes = ByteReader.ReadBytes(buffer, ref offset, hintLength); return(DerEncodingHelper.DecodeGeneralString(hintNameBytes)); }
/// <summary> /// https://tools.ietf.org/html/rfc2743 /// </summary> /// <exception cref="System.IO.InvalidDataException"></exception> public static SimpleProtectedNegotiationToken ReadToken(byte[] tokenBytes, int offset, bool serverInitiatedNegotiation) { byte tag = ByteReader.ReadByte(tokenBytes, ref offset); if (tag == ApplicationTag) { // https://msdn.microsoft.com/en-us/library/ms995330.aspx // when an InitToken is sent, it is prepended by an Application Constructed Object specifier (0x60), // and the OID for SPNEGO. This is the generic GSSAPI header. // [RFC 2743] The use of the Mechanism-Independent Token Format is required for initial context // establishment tokens, use in non-initial tokens is optional. int tokenLength = DerEncodingHelper.ReadLength(tokenBytes, ref offset); tag = ByteReader.ReadByte(tokenBytes, ref offset); if (tag == (byte)DerEncodingTag.ObjectIdentifier) { int objectIdentifierLength = DerEncodingHelper.ReadLength(tokenBytes, ref offset); byte[] objectIdentifier = ByteReader.ReadBytes(tokenBytes, ref offset, objectIdentifierLength); if (ByteUtils.AreByteArraysEqual(objectIdentifier, SPNEGOIdentifier)) { tag = ByteReader.ReadByte(tokenBytes, ref offset); if (tag == SimpleProtectedNegotiationTokenInit.NegTokenInitTag) { if (serverInitiatedNegotiation) { // [MS-SPNG] Standard GSS has a strict notion of client (initiator) and server (acceptor). // If the client has not sent a negTokenInit ([RFC4178] section 4.2.1) message, no context establishment token is expected from the server. // The [NegTokenInit2] SPNEGO extension allows the server to generate a context establishment token message [..] and send it to the client. return(new SimpleProtectedNegotiationTokenInit2(tokenBytes, offset)); } else { return(new SimpleProtectedNegotiationTokenInit(tokenBytes, offset)); } } else if (tag == SimpleProtectedNegotiationTokenResponse.NegTokenRespTag) { return(new SimpleProtectedNegotiationTokenResponse(tokenBytes, offset)); } } } } else if (tag == SimpleProtectedNegotiationTokenResponse.NegTokenRespTag) { return(new SimpleProtectedNegotiationTokenResponse(tokenBytes, offset)); } return(null); }
/// <param name="offset">The offset following the NegTokenInit2 tag</param> /// <exception cref="System.IO.InvalidDataException"></exception> public SimpleProtectedNegotiationTokenInit2(byte[] buffer, int offset) { int constructionLength = DerEncodingHelper.ReadLength(buffer, ref offset); byte tag = ByteReader.ReadByte(buffer, ref offset); if (tag != (byte)DerEncodingTag.Sequence) { throw new InvalidDataException(); } int sequenceLength = DerEncodingHelper.ReadLength(buffer, ref offset); int sequenceEndOffset = offset + sequenceLength; while (offset < sequenceEndOffset) { tag = ByteReader.ReadByte(buffer, ref offset); if (tag == MechanismTypeListTag) { MechanismTypeList = ReadMechanismTypeList(buffer, ref offset); } else if (tag == RequiredFlagsTag) { throw new NotImplementedException("negTokenInit.ReqFlags is not implemented"); } else if (tag == MechanismTokenTag) { MechanismToken = ReadMechanismToken(buffer, ref offset); } else if (tag == NegHintsTag) { HintName = ReadHints(buffer, ref offset, out HintAddress); } else if (tag == MechanismListMICTag) { MechanismListMIC = ReadMechanismListMIC(buffer, ref offset); } else { throw new InvalidDataException("Invalid negTokenInit structure"); } } }
/// <summary> /// https://tools.ietf.org/html/rfc2743 /// </summary> /// <exception cref="System.IO.InvalidDataException"></exception> public static SimpleProtectedNegotiationToken ReadToken(byte[] tokenBytes, int offset) { byte tag = ByteReader.ReadByte(tokenBytes, ref offset); if (tag == ApplicationTag) { // https://msdn.microsoft.com/en-us/library/ms995330.aspx // when an InitToken is sent, it is prepended by an Application Constructed Object specifier (0x60), // and the OID for SPNEGO. This is the generic GSSAPI header. // [RFC 2743] The use of the Mechanism-Independent Token Format is required for initial context // establishment tokens, use in non-initial tokens is optional. int tokenLength = DerEncodingHelper.ReadLength(tokenBytes, ref offset); tag = ByteReader.ReadByte(tokenBytes, ref offset); if (tag == (byte)DerEncodingTag.ObjectIdentifier) { int objectIdentifierLength = DerEncodingHelper.ReadLength(tokenBytes, ref offset); byte[] objectIdentifier = ByteReader.ReadBytes(tokenBytes, ref offset, objectIdentifierLength); if (ByteUtils.AreByteArraysEqual(objectIdentifier, SPNEGOIdentifier)) { tag = ByteReader.ReadByte(tokenBytes, ref offset); if (tag == SimpleProtectedNegotiationTokenInit.NegTokenInitTag) { return(new SimpleProtectedNegotiationTokenInit(tokenBytes, offset)); } else if (tag == SimpleProtectedNegotiationTokenResponse.NegTokenRespTag) { return(new SimpleProtectedNegotiationTokenResponse(tokenBytes, offset)); } } } } else if (tag == SimpleProtectedNegotiationTokenResponse.NegTokenRespTag) { return(new SimpleProtectedNegotiationTokenResponse(tokenBytes, offset)); } return(null); }
/// <param name="offset">The offset following the NegTokenResp tag</param> /// <exception cref="System.IO.InvalidDataException"></exception> public SimpleProtectedNegotiationTokenResponse(byte[] buffer, int offset) { int constuctionLength = DerEncodingHelper.ReadLength(buffer, ref offset); byte tag = ByteReader.ReadByte(buffer, ref offset); if (tag != (byte)DerEncodingTag.Sequence) { throw new InvalidDataException(); } int sequenceLength = DerEncodingHelper.ReadLength(buffer, ref offset); int sequenceEndOffset = offset + sequenceLength; while (offset < sequenceEndOffset) { tag = ByteReader.ReadByte(buffer, ref offset); if (tag == NegStateTag) { NegState = ReadNegState(buffer, ref offset); } else if (tag == SupportedMechanismTag) { SupportedMechanism = ReadSupportedMechanism(buffer, ref offset); } else if (tag == ResponseTokenTag) { ResponseToken = ReadResponseToken(buffer, ref offset); } else if (tag == MechanismListMICTag) { MechanismListMIC = ReadMechanismListMIC(buffer, ref offset); } else { throw new InvalidDataException("Invalid negTokenResp structure"); } } }