xref: /aosp_15_r20/external/cronet/net/ntlm/ntlm_buffer_reader.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2017 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "net/ntlm/ntlm_buffer_reader.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <string.h>
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include "base/check_op.h"
10*6777b538SAndroid Build Coastguard Worker 
11*6777b538SAndroid Build Coastguard Worker namespace net::ntlm {
12*6777b538SAndroid Build Coastguard Worker 
13*6777b538SAndroid Build Coastguard Worker NtlmBufferReader::NtlmBufferReader() = default;
14*6777b538SAndroid Build Coastguard Worker 
NtlmBufferReader(base::span<const uint8_t> buffer)15*6777b538SAndroid Build Coastguard Worker NtlmBufferReader::NtlmBufferReader(base::span<const uint8_t> buffer)
16*6777b538SAndroid Build Coastguard Worker     : buffer_(buffer) {}
17*6777b538SAndroid Build Coastguard Worker 
18*6777b538SAndroid Build Coastguard Worker NtlmBufferReader::~NtlmBufferReader() = default;
19*6777b538SAndroid Build Coastguard Worker 
CanRead(size_t len) const20*6777b538SAndroid Build Coastguard Worker bool NtlmBufferReader::CanRead(size_t len) const {
21*6777b538SAndroid Build Coastguard Worker   return CanReadFrom(GetCursor(), len);
22*6777b538SAndroid Build Coastguard Worker }
23*6777b538SAndroid Build Coastguard Worker 
CanReadFrom(size_t offset,size_t len) const24*6777b538SAndroid Build Coastguard Worker bool NtlmBufferReader::CanReadFrom(size_t offset, size_t len) const {
25*6777b538SAndroid Build Coastguard Worker   if (len == 0)
26*6777b538SAndroid Build Coastguard Worker     return true;
27*6777b538SAndroid Build Coastguard Worker 
28*6777b538SAndroid Build Coastguard Worker   return (len <= GetLength() && offset <= GetLength() - len);
29*6777b538SAndroid Build Coastguard Worker }
30*6777b538SAndroid Build Coastguard Worker 
ReadUInt16(uint16_t * value)31*6777b538SAndroid Build Coastguard Worker bool NtlmBufferReader::ReadUInt16(uint16_t* value) {
32*6777b538SAndroid Build Coastguard Worker   return ReadUInt<uint16_t>(value);
33*6777b538SAndroid Build Coastguard Worker }
34*6777b538SAndroid Build Coastguard Worker 
ReadUInt32(uint32_t * value)35*6777b538SAndroid Build Coastguard Worker bool NtlmBufferReader::ReadUInt32(uint32_t* value) {
36*6777b538SAndroid Build Coastguard Worker   return ReadUInt<uint32_t>(value);
37*6777b538SAndroid Build Coastguard Worker }
38*6777b538SAndroid Build Coastguard Worker 
ReadUInt64(uint64_t * value)39*6777b538SAndroid Build Coastguard Worker bool NtlmBufferReader::ReadUInt64(uint64_t* value) {
40*6777b538SAndroid Build Coastguard Worker   return ReadUInt<uint64_t>(value);
41*6777b538SAndroid Build Coastguard Worker }
42*6777b538SAndroid Build Coastguard Worker 
ReadFlags(NegotiateFlags * flags)43*6777b538SAndroid Build Coastguard Worker bool NtlmBufferReader::ReadFlags(NegotiateFlags* flags) {
44*6777b538SAndroid Build Coastguard Worker   uint32_t raw;
45*6777b538SAndroid Build Coastguard Worker   if (!ReadUInt32(&raw))
46*6777b538SAndroid Build Coastguard Worker     return false;
47*6777b538SAndroid Build Coastguard Worker 
48*6777b538SAndroid Build Coastguard Worker   *flags = static_cast<NegotiateFlags>(raw);
49*6777b538SAndroid Build Coastguard Worker   return true;
50*6777b538SAndroid Build Coastguard Worker }
51*6777b538SAndroid Build Coastguard Worker 
ReadBytes(base::span<uint8_t> buffer)52*6777b538SAndroid Build Coastguard Worker bool NtlmBufferReader::ReadBytes(base::span<uint8_t> buffer) {
53*6777b538SAndroid Build Coastguard Worker   if (!CanRead(buffer.size()))
54*6777b538SAndroid Build Coastguard Worker     return false;
55*6777b538SAndroid Build Coastguard Worker 
56*6777b538SAndroid Build Coastguard Worker   if (buffer.empty())
57*6777b538SAndroid Build Coastguard Worker     return true;
58*6777b538SAndroid Build Coastguard Worker 
59*6777b538SAndroid Build Coastguard Worker   memcpy(buffer.data(), GetBufferAtCursor(), buffer.size());
60*6777b538SAndroid Build Coastguard Worker 
61*6777b538SAndroid Build Coastguard Worker   AdvanceCursor(buffer.size());
62*6777b538SAndroid Build Coastguard Worker   return true;
63*6777b538SAndroid Build Coastguard Worker }
64*6777b538SAndroid Build Coastguard Worker 
ReadBytesFrom(const SecurityBuffer & sec_buf,base::span<uint8_t> buffer)65*6777b538SAndroid Build Coastguard Worker bool NtlmBufferReader::ReadBytesFrom(const SecurityBuffer& sec_buf,
66*6777b538SAndroid Build Coastguard Worker                                      base::span<uint8_t> buffer) {
67*6777b538SAndroid Build Coastguard Worker   if (!CanReadFrom(sec_buf) || buffer.size() < sec_buf.length)
68*6777b538SAndroid Build Coastguard Worker     return false;
69*6777b538SAndroid Build Coastguard Worker 
70*6777b538SAndroid Build Coastguard Worker   if (buffer.empty())
71*6777b538SAndroid Build Coastguard Worker     return true;
72*6777b538SAndroid Build Coastguard Worker 
73*6777b538SAndroid Build Coastguard Worker   memcpy(buffer.data(), GetBufferPtr() + sec_buf.offset, sec_buf.length);
74*6777b538SAndroid Build Coastguard Worker 
75*6777b538SAndroid Build Coastguard Worker   return true;
76*6777b538SAndroid Build Coastguard Worker }
77*6777b538SAndroid Build Coastguard Worker 
ReadPayloadAsBufferReader(const SecurityBuffer & sec_buf,NtlmBufferReader * reader)78*6777b538SAndroid Build Coastguard Worker bool NtlmBufferReader::ReadPayloadAsBufferReader(const SecurityBuffer& sec_buf,
79*6777b538SAndroid Build Coastguard Worker                                                  NtlmBufferReader* reader) {
80*6777b538SAndroid Build Coastguard Worker   if (!CanReadFrom(sec_buf))
81*6777b538SAndroid Build Coastguard Worker     return false;
82*6777b538SAndroid Build Coastguard Worker 
83*6777b538SAndroid Build Coastguard Worker   *reader = NtlmBufferReader(
84*6777b538SAndroid Build Coastguard Worker       base::make_span(GetBufferPtr() + sec_buf.offset, sec_buf.length));
85*6777b538SAndroid Build Coastguard Worker   return true;
86*6777b538SAndroid Build Coastguard Worker }
87*6777b538SAndroid Build Coastguard Worker 
ReadSecurityBuffer(SecurityBuffer * sec_buf)88*6777b538SAndroid Build Coastguard Worker bool NtlmBufferReader::ReadSecurityBuffer(SecurityBuffer* sec_buf) {
89*6777b538SAndroid Build Coastguard Worker   return ReadUInt16(&sec_buf->length) && SkipBytes(sizeof(uint16_t)) &&
90*6777b538SAndroid Build Coastguard Worker          ReadUInt32(&sec_buf->offset);
91*6777b538SAndroid Build Coastguard Worker }
92*6777b538SAndroid Build Coastguard Worker 
ReadAvPairHeader(TargetInfoAvId * avid,uint16_t * avlen)93*6777b538SAndroid Build Coastguard Worker bool NtlmBufferReader::ReadAvPairHeader(TargetInfoAvId* avid, uint16_t* avlen) {
94*6777b538SAndroid Build Coastguard Worker   if (!CanRead(kAvPairHeaderLen))
95*6777b538SAndroid Build Coastguard Worker     return false;
96*6777b538SAndroid Build Coastguard Worker 
97*6777b538SAndroid Build Coastguard Worker   uint16_t raw_avid;
98*6777b538SAndroid Build Coastguard Worker   bool result = ReadUInt16(&raw_avid) && ReadUInt16(avlen);
99*6777b538SAndroid Build Coastguard Worker   DCHECK(result);
100*6777b538SAndroid Build Coastguard Worker 
101*6777b538SAndroid Build Coastguard Worker   // Don't try and validate the avid because the code only cares about a few
102*6777b538SAndroid Build Coastguard Worker   // specific ones and it is likely a future version might extend this field.
103*6777b538SAndroid Build Coastguard Worker   // The implementation can ignore and skip over AV Pairs it doesn't
104*6777b538SAndroid Build Coastguard Worker   // understand.
105*6777b538SAndroid Build Coastguard Worker   *avid = static_cast<TargetInfoAvId>(raw_avid);
106*6777b538SAndroid Build Coastguard Worker 
107*6777b538SAndroid Build Coastguard Worker   return true;
108*6777b538SAndroid Build Coastguard Worker }
109*6777b538SAndroid Build Coastguard Worker 
ReadTargetInfo(size_t target_info_len,std::vector<AvPair> * av_pairs)110*6777b538SAndroid Build Coastguard Worker bool NtlmBufferReader::ReadTargetInfo(size_t target_info_len,
111*6777b538SAndroid Build Coastguard Worker                                       std::vector<AvPair>* av_pairs) {
112*6777b538SAndroid Build Coastguard Worker   DCHECK(av_pairs->empty());
113*6777b538SAndroid Build Coastguard Worker 
114*6777b538SAndroid Build Coastguard Worker   // A completely empty target info is allowed.
115*6777b538SAndroid Build Coastguard Worker   if (target_info_len == 0)
116*6777b538SAndroid Build Coastguard Worker     return true;
117*6777b538SAndroid Build Coastguard Worker 
118*6777b538SAndroid Build Coastguard Worker   // If there is any content there has to be at least one terminating header.
119*6777b538SAndroid Build Coastguard Worker   if (!CanRead(target_info_len) || target_info_len < kAvPairHeaderLen) {
120*6777b538SAndroid Build Coastguard Worker     return false;
121*6777b538SAndroid Build Coastguard Worker   }
122*6777b538SAndroid Build Coastguard Worker 
123*6777b538SAndroid Build Coastguard Worker   size_t target_info_end = GetCursor() + target_info_len;
124*6777b538SAndroid Build Coastguard Worker   bool saw_eol = false;
125*6777b538SAndroid Build Coastguard Worker 
126*6777b538SAndroid Build Coastguard Worker   while ((GetCursor() < target_info_end)) {
127*6777b538SAndroid Build Coastguard Worker     AvPair pair;
128*6777b538SAndroid Build Coastguard Worker     if (!ReadAvPairHeader(&pair.avid, &pair.avlen))
129*6777b538SAndroid Build Coastguard Worker       break;
130*6777b538SAndroid Build Coastguard Worker 
131*6777b538SAndroid Build Coastguard Worker     // Make sure the length wouldn't read outside the buffer.
132*6777b538SAndroid Build Coastguard Worker     if (!CanRead(pair.avlen))
133*6777b538SAndroid Build Coastguard Worker       return false;
134*6777b538SAndroid Build Coastguard Worker 
135*6777b538SAndroid Build Coastguard Worker     // Take a copy of the payload in the AVPair.
136*6777b538SAndroid Build Coastguard Worker     pair.buffer.assign(GetBufferAtCursor(), GetBufferAtCursor() + pair.avlen);
137*6777b538SAndroid Build Coastguard Worker     if (pair.avid == TargetInfoAvId::kEol) {
138*6777b538SAndroid Build Coastguard Worker       // Terminator must have zero length.
139*6777b538SAndroid Build Coastguard Worker       if (pair.avlen != 0)
140*6777b538SAndroid Build Coastguard Worker         return false;
141*6777b538SAndroid Build Coastguard Worker 
142*6777b538SAndroid Build Coastguard Worker       // Break out of the loop once a valid terminator is found. After the
143*6777b538SAndroid Build Coastguard Worker       // loop it will be validated that the whole target info was consumed.
144*6777b538SAndroid Build Coastguard Worker       saw_eol = true;
145*6777b538SAndroid Build Coastguard Worker       break;
146*6777b538SAndroid Build Coastguard Worker     }
147*6777b538SAndroid Build Coastguard Worker 
148*6777b538SAndroid Build Coastguard Worker     switch (pair.avid) {
149*6777b538SAndroid Build Coastguard Worker       case TargetInfoAvId::kFlags:
150*6777b538SAndroid Build Coastguard Worker         // For flags also populate the flags field so it doesn't
151*6777b538SAndroid Build Coastguard Worker         // have to be modified through the raw buffer later.
152*6777b538SAndroid Build Coastguard Worker         if (pair.avlen != sizeof(uint32_t) ||
153*6777b538SAndroid Build Coastguard Worker             !ReadUInt32(reinterpret_cast<uint32_t*>(&pair.flags)))
154*6777b538SAndroid Build Coastguard Worker           return false;
155*6777b538SAndroid Build Coastguard Worker         break;
156*6777b538SAndroid Build Coastguard Worker       case TargetInfoAvId::kTimestamp:
157*6777b538SAndroid Build Coastguard Worker         // Populate timestamp so it doesn't need to be read through the
158*6777b538SAndroid Build Coastguard Worker         // raw buffer later.
159*6777b538SAndroid Build Coastguard Worker         if (pair.avlen != sizeof(uint64_t) || !ReadUInt64(&pair.timestamp))
160*6777b538SAndroid Build Coastguard Worker           return false;
161*6777b538SAndroid Build Coastguard Worker         break;
162*6777b538SAndroid Build Coastguard Worker       case TargetInfoAvId::kChannelBindings:
163*6777b538SAndroid Build Coastguard Worker       case TargetInfoAvId::kTargetName:
164*6777b538SAndroid Build Coastguard Worker         // The server should never send these, and with EPA enabled the client
165*6777b538SAndroid Build Coastguard Worker         // will add these to the authenticate message. To avoid issues with
166*6777b538SAndroid Build Coastguard Worker         // duplicates or only one being read, just don't allow them.
167*6777b538SAndroid Build Coastguard Worker         return false;
168*6777b538SAndroid Build Coastguard Worker       default:
169*6777b538SAndroid Build Coastguard Worker         // For all other types, just jump over the payload to the next pair.
170*6777b538SAndroid Build Coastguard Worker         // If there aren't enough bytes left, then fail.
171*6777b538SAndroid Build Coastguard Worker         if (!SkipBytes(pair.avlen))
172*6777b538SAndroid Build Coastguard Worker           return false;
173*6777b538SAndroid Build Coastguard Worker         break;
174*6777b538SAndroid Build Coastguard Worker     }
175*6777b538SAndroid Build Coastguard Worker 
176*6777b538SAndroid Build Coastguard Worker     av_pairs->push_back(std::move(pair));
177*6777b538SAndroid Build Coastguard Worker   }
178*6777b538SAndroid Build Coastguard Worker 
179*6777b538SAndroid Build Coastguard Worker   // Fail if the buffer wasn't properly formed. The entire payload should have
180*6777b538SAndroid Build Coastguard Worker   // been consumed and a terminator found.
181*6777b538SAndroid Build Coastguard Worker   if ((GetCursor() != target_info_end) || !saw_eol)
182*6777b538SAndroid Build Coastguard Worker     return false;
183*6777b538SAndroid Build Coastguard Worker 
184*6777b538SAndroid Build Coastguard Worker   return true;
185*6777b538SAndroid Build Coastguard Worker }
186*6777b538SAndroid Build Coastguard Worker 
ReadTargetInfoPayload(std::vector<AvPair> * av_pairs)187*6777b538SAndroid Build Coastguard Worker bool NtlmBufferReader::ReadTargetInfoPayload(std::vector<AvPair>* av_pairs) {
188*6777b538SAndroid Build Coastguard Worker   DCHECK(av_pairs->empty());
189*6777b538SAndroid Build Coastguard Worker 
190*6777b538SAndroid Build Coastguard Worker   SecurityBuffer sec_buf;
191*6777b538SAndroid Build Coastguard Worker 
192*6777b538SAndroid Build Coastguard Worker   // First read the security buffer.
193*6777b538SAndroid Build Coastguard Worker   if (!ReadSecurityBuffer(&sec_buf))
194*6777b538SAndroid Build Coastguard Worker     return false;
195*6777b538SAndroid Build Coastguard Worker 
196*6777b538SAndroid Build Coastguard Worker   NtlmBufferReader payload_reader;
197*6777b538SAndroid Build Coastguard Worker   if (!ReadPayloadAsBufferReader(sec_buf, &payload_reader))
198*6777b538SAndroid Build Coastguard Worker     return false;
199*6777b538SAndroid Build Coastguard Worker 
200*6777b538SAndroid Build Coastguard Worker   if (!payload_reader.ReadTargetInfo(sec_buf.length, av_pairs))
201*6777b538SAndroid Build Coastguard Worker     return false;
202*6777b538SAndroid Build Coastguard Worker 
203*6777b538SAndroid Build Coastguard Worker   // |ReadTargetInfo| should have consumed the entire contents.
204*6777b538SAndroid Build Coastguard Worker   return payload_reader.IsEndOfBuffer();
205*6777b538SAndroid Build Coastguard Worker }
206*6777b538SAndroid Build Coastguard Worker 
ReadMessageType(MessageType * message_type)207*6777b538SAndroid Build Coastguard Worker bool NtlmBufferReader::ReadMessageType(MessageType* message_type) {
208*6777b538SAndroid Build Coastguard Worker   uint32_t raw_message_type;
209*6777b538SAndroid Build Coastguard Worker   if (!ReadUInt32(&raw_message_type))
210*6777b538SAndroid Build Coastguard Worker     return false;
211*6777b538SAndroid Build Coastguard Worker 
212*6777b538SAndroid Build Coastguard Worker   *message_type = static_cast<MessageType>(raw_message_type);
213*6777b538SAndroid Build Coastguard Worker 
214*6777b538SAndroid Build Coastguard Worker   if (*message_type != MessageType::kNegotiate &&
215*6777b538SAndroid Build Coastguard Worker       *message_type != MessageType::kChallenge &&
216*6777b538SAndroid Build Coastguard Worker       *message_type != MessageType::kAuthenticate)
217*6777b538SAndroid Build Coastguard Worker     return false;
218*6777b538SAndroid Build Coastguard Worker 
219*6777b538SAndroid Build Coastguard Worker   return true;
220*6777b538SAndroid Build Coastguard Worker }
221*6777b538SAndroid Build Coastguard Worker 
SkipSecurityBuffer()222*6777b538SAndroid Build Coastguard Worker bool NtlmBufferReader::SkipSecurityBuffer() {
223*6777b538SAndroid Build Coastguard Worker   return SkipBytes(kSecurityBufferLen);
224*6777b538SAndroid Build Coastguard Worker }
225*6777b538SAndroid Build Coastguard Worker 
SkipSecurityBufferWithValidation()226*6777b538SAndroid Build Coastguard Worker bool NtlmBufferReader::SkipSecurityBufferWithValidation() {
227*6777b538SAndroid Build Coastguard Worker   SecurityBuffer sec_buf;
228*6777b538SAndroid Build Coastguard Worker   return ReadSecurityBuffer(&sec_buf) && CanReadFrom(sec_buf);
229*6777b538SAndroid Build Coastguard Worker }
230*6777b538SAndroid Build Coastguard Worker 
SkipBytes(size_t count)231*6777b538SAndroid Build Coastguard Worker bool NtlmBufferReader::SkipBytes(size_t count) {
232*6777b538SAndroid Build Coastguard Worker   if (!CanRead(count))
233*6777b538SAndroid Build Coastguard Worker     return false;
234*6777b538SAndroid Build Coastguard Worker 
235*6777b538SAndroid Build Coastguard Worker   AdvanceCursor(count);
236*6777b538SAndroid Build Coastguard Worker   return true;
237*6777b538SAndroid Build Coastguard Worker }
238*6777b538SAndroid Build Coastguard Worker 
MatchSignature()239*6777b538SAndroid Build Coastguard Worker bool NtlmBufferReader::MatchSignature() {
240*6777b538SAndroid Build Coastguard Worker   if (!CanRead(kSignatureLen))
241*6777b538SAndroid Build Coastguard Worker     return false;
242*6777b538SAndroid Build Coastguard Worker 
243*6777b538SAndroid Build Coastguard Worker   if (memcmp(kSignature, GetBufferAtCursor(), kSignatureLen) != 0)
244*6777b538SAndroid Build Coastguard Worker     return false;
245*6777b538SAndroid Build Coastguard Worker 
246*6777b538SAndroid Build Coastguard Worker   AdvanceCursor(kSignatureLen);
247*6777b538SAndroid Build Coastguard Worker   return true;
248*6777b538SAndroid Build Coastguard Worker }
249*6777b538SAndroid Build Coastguard Worker 
MatchMessageType(MessageType message_type)250*6777b538SAndroid Build Coastguard Worker bool NtlmBufferReader::MatchMessageType(MessageType message_type) {
251*6777b538SAndroid Build Coastguard Worker   MessageType actual_message_type;
252*6777b538SAndroid Build Coastguard Worker   return ReadMessageType(&actual_message_type) &&
253*6777b538SAndroid Build Coastguard Worker          (actual_message_type == message_type);
254*6777b538SAndroid Build Coastguard Worker }
255*6777b538SAndroid Build Coastguard Worker 
MatchMessageHeader(MessageType message_type)256*6777b538SAndroid Build Coastguard Worker bool NtlmBufferReader::MatchMessageHeader(MessageType message_type) {
257*6777b538SAndroid Build Coastguard Worker   return MatchSignature() && MatchMessageType(message_type);
258*6777b538SAndroid Build Coastguard Worker }
259*6777b538SAndroid Build Coastguard Worker 
MatchZeros(size_t count)260*6777b538SAndroid Build Coastguard Worker bool NtlmBufferReader::MatchZeros(size_t count) {
261*6777b538SAndroid Build Coastguard Worker   if (!CanRead(count))
262*6777b538SAndroid Build Coastguard Worker     return false;
263*6777b538SAndroid Build Coastguard Worker 
264*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < count; i++) {
265*6777b538SAndroid Build Coastguard Worker     if (GetBufferAtCursor()[i] != 0)
266*6777b538SAndroid Build Coastguard Worker       return false;
267*6777b538SAndroid Build Coastguard Worker   }
268*6777b538SAndroid Build Coastguard Worker 
269*6777b538SAndroid Build Coastguard Worker   AdvanceCursor(count);
270*6777b538SAndroid Build Coastguard Worker   return true;
271*6777b538SAndroid Build Coastguard Worker }
272*6777b538SAndroid Build Coastguard Worker 
MatchEmptySecurityBuffer()273*6777b538SAndroid Build Coastguard Worker bool NtlmBufferReader::MatchEmptySecurityBuffer() {
274*6777b538SAndroid Build Coastguard Worker   SecurityBuffer sec_buf;
275*6777b538SAndroid Build Coastguard Worker   return ReadSecurityBuffer(&sec_buf) && (sec_buf.offset <= GetLength()) &&
276*6777b538SAndroid Build Coastguard Worker          (sec_buf.length == 0);
277*6777b538SAndroid Build Coastguard Worker }
278*6777b538SAndroid Build Coastguard Worker 
279*6777b538SAndroid Build Coastguard Worker template <typename T>
ReadUInt(T * value)280*6777b538SAndroid Build Coastguard Worker bool NtlmBufferReader::ReadUInt(T* value) {
281*6777b538SAndroid Build Coastguard Worker   size_t int_size = sizeof(T);
282*6777b538SAndroid Build Coastguard Worker   if (!CanRead(int_size))
283*6777b538SAndroid Build Coastguard Worker     return false;
284*6777b538SAndroid Build Coastguard Worker 
285*6777b538SAndroid Build Coastguard Worker   *value = 0;
286*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < int_size; i++) {
287*6777b538SAndroid Build Coastguard Worker     *value += static_cast<T>(GetByteAtCursor()) << (i * 8);
288*6777b538SAndroid Build Coastguard Worker     AdvanceCursor(1);
289*6777b538SAndroid Build Coastguard Worker   }
290*6777b538SAndroid Build Coastguard Worker 
291*6777b538SAndroid Build Coastguard Worker   return true;
292*6777b538SAndroid Build Coastguard Worker }
293*6777b538SAndroid Build Coastguard Worker 
SetCursor(size_t cursor)294*6777b538SAndroid Build Coastguard Worker void NtlmBufferReader::SetCursor(size_t cursor) {
295*6777b538SAndroid Build Coastguard Worker   DCHECK_LE(cursor, GetLength());
296*6777b538SAndroid Build Coastguard Worker 
297*6777b538SAndroid Build Coastguard Worker   cursor_ = cursor;
298*6777b538SAndroid Build Coastguard Worker }
299*6777b538SAndroid Build Coastguard Worker 
300*6777b538SAndroid Build Coastguard Worker }  // namespace net::ntlm
301