Beispiel #1
0
        public unsafe string ProcessNegotiateChallenge(string challengeString)
        {
            Console.WriteLine($"ChallengesString {challengeString}");

            NegState state = NegState.Unknown;
            string   mech  = null;

            byte[] blob = null;

            byte[]    data            = Convert.FromBase64String(challengeString);
            AsnReader reader          = new AsnReader(data, AsnEncodingRules.DER);
            AsnReader challengeReader = reader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegotiationToken.NegTokenResp));

            // NegTokenResp::= SEQUENCE {
            //    negState[0] ENUMERATED {
            //        accept - completed(0),
            //        accept - incomplete(1),
            //        reject(2),
            //        request - mic(3)
            //    } OPTIONAL,
            // --REQUIRED in the first reply from the target
            //    supportedMech[1] MechType OPTIONAL,
            // --present only in the first reply from the target
            // responseToken[2] OCTET STRING  OPTIONAL,
            // mechListMIC[3] OCTET STRING  OPTIONAL,
            // ...
            // }

            challengeReader = challengeReader.ReadSequence();
            while (challengeReader.HasData)
            {
                Asn1Tag tag = challengeReader.PeekTag();
                if (tag.TagClass == TagClass.ContextSpecific)
                {
                    NegTokenResp dataType      = (NegTokenResp)tag.TagValue;
                    AsnReader    specificValue = new AsnReader(challengeReader.PeekContentBytes(), AsnEncodingRules.DER);

                    switch (dataType)
                    {
                    case NegTokenResp.NegState:
                        state = specificValue.ReadEnumeratedValue <NegState>();
                        break;

                    case NegTokenResp.SupportedMech:
                        mech = specificValue.ReadObjectIdentifier();
                        break;

                    case NegTokenResp.ResponseToken:
                        blob = specificValue.ReadOctetString();
                        break;

                    default:
                        // Ignore everything else
                        break;
                    }
                }

                challengeReader.ReadEncodedValue();
            }

            if (Diag)
            {
                Console.WriteLine("Negotiate challenege: {0} - {1} in {2}", challengeString, mech, state);
            }

            // Mechanism should be set on first message. That means always
            // as NTLM has only one challenege message.
            if (!NtlmOid.Equals(mech))
            {
                throw new NotSupportedException($"'{mech}' mechanism is not supported");
            }


            if (state != NegState.Unknown && state != NegState.AcceptIncomplete)
            {
                // If state was set, it should be AcceptIncomplete for us to proseed.
                return("");
            }

            if (blob?.Length > 0)
            {
                // Process decoded NTLM blob.
                byte[] response = ProcessChallengeMessage(blob);
                if (response?.Length > 0)
                {
                    AsnWriter writer = new AsnWriter(AsnEncodingRules.DER);

                    using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegotiationToken.NegTokenResp)))
                    {
                        writer.PushSequence();
                        using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenInit.MechToken)))
                        {
                            writer.WriteOctetString(response);
                        }

                        writer.PopSequence();
                    }

                    return("Negotiate " + Convert.ToBase64String(writer.Encode(), Base64FormattingOptions.None));
                }
            }

            return("");
        }
 /// <summary>
 /// Constructor
 /// Generally used when encoding
 /// </summary>
 /// <param name="token">The Asn.1 formatted token contains in the class</param>
 public SpngNegTokenResp(NegTokenResp token)
     : base(token)
 {
 }