public NtlmMessage(ReadOnlyMemory <byte> ntlm) { bool canRead; BinaryReader reader; do { canRead = CanReadNtlmMessage(ntlm, out byte[] actualSignature, out reader, out AsnReader asnReader); if (!canRead) { throw new InvalidDataException($"Unknown NTLM message signature. Actual: 0x{actualSignature:X}; Expected: 0x{MessageSignature:X}"); } if (asnReader == null) { break; } asnReader = asnReader.ReadSequence(NtlmContextTag); NegTokenResp.Decode(asnReader, out NegTokenResp resp); ntlm = resp.ResponseToken.Value; }while (canRead); MessageType = (NtlmMessageType)reader.ReadInt32(); if (MessageType != NtlmMessageType.Challenge) { return; } Flags = (NtlmNegotiateFlag)reader.ReadInt32(); var domainNameLength = reader.ReadInt16(); var domainNameMaxLength = reader.ReadInt16(); var domainNameBufferOffset = reader.ReadInt32(); var workstationLength = reader.ReadInt16(); var workstationMaxLength = reader.ReadInt16(); var workstationBufferOffset = reader.ReadInt32(); var version = reader.ReadInt64(); if ((Flags & NtlmNegotiateFlag.NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED) > 0) { reader.BaseStream.Seek(domainNameBufferOffset, SeekOrigin.Begin); DomainName = Encoding.ASCII.GetString(reader.ReadBytes(domainNameLength)); } if ((Flags & NtlmNegotiateFlag.NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED) > 0) { reader.BaseStream.Seek(workstationBufferOffset, SeekOrigin.Begin); Workstation = Encoding.ASCII.GetString(reader.ReadBytes(workstationLength)); } reader.Dispose(); }
internal static void Decode <T>(AsnReader reader, out T decoded) where T : NegotiationToken, new() { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = new T(); Asn1Tag tag = reader.PeekTag(); AsnReader explicitReader; if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0))) { explicitReader = reader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); NegTokenInit.Decode <NegTokenInit>(explicitReader, out NegTokenInit tmpInitialToken); decoded.InitialToken = tmpInitialToken; explicitReader.ThrowIfNotEmpty(); } else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1))) { explicitReader = reader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 1)); NegTokenResp.Decode <NegTokenResp>(explicitReader, out NegTokenResp tmpResponseToken); decoded.ResponseToken = tmpResponseToken; explicitReader.ThrowIfNotEmpty(); } else { throw new CryptographicException(); } }