MCPcopy
hub / github.com/jackc/pgx / recvServerFirstMessage

Method recvServerFirstMessage

pgconn/auth_scram.go:244–304  ·  view source on GitHub ↗
(serverFirstMessage []byte)

Source from the content-addressed store, hash-verified

242}
243
244func (sc *scramClient) recvServerFirstMessage(serverFirstMessage []byte) error {
245 sc.serverFirstMessage = serverFirstMessage
246 buf := serverFirstMessage
247 if !bytes.HasPrefix(buf, []byte("r=")) {
248 return errors.New("invalid SCRAM server-first-message received from server: did not include r=")
249 }
250 buf = buf[2:]
251
252 idx := bytes.IndexByte(buf, ',')
253 if idx == -1 {
254 return errors.New("invalid SCRAM server-first-message received from server: did not include s=")
255 }
256 sc.clientAndServerNonce = buf[:idx]
257 buf = buf[idx+1:]
258
259 if !bytes.HasPrefix(buf, []byte("s=")) {
260 return errors.New("invalid SCRAM server-first-message received from server: did not include s=")
261 }
262 buf = buf[2:]
263
264 idx = bytes.IndexByte(buf, ',')
265 if idx == -1 {
266 return errors.New("invalid SCRAM server-first-message received from server: did not include i=")
267 }
268 saltStr := buf[:idx]
269 buf = buf[idx+1:]
270
271 if !bytes.HasPrefix(buf, []byte("i=")) {
272 return errors.New("invalid SCRAM server-first-message received from server: did not include i=")
273 }
274 buf = buf[2:]
275 iterationsStr := buf
276
277 var err error
278 sc.salt, err = base64.StdEncoding.DecodeString(string(saltStr))
279 if err != nil {
280 return fmt.Errorf("invalid SCRAM salt received from server: %w", err)
281 }
282
283 sc.iterations, err = strconv.Atoi(string(iterationsStr))
284 if err != nil || sc.iterations <= 0 {
285 return fmt.Errorf("invalid SCRAM iteration count received from server: %w", err)
286 }
287 // Bound server-supplied iteration count to prevent a malicious server from forcing the client
288 // to spend unbounded CPU in PBKDF2. PostgreSQL's scram_iterations defaults to 4096; this ceiling
289 // is ~2500x that.
290 const maxScramIterations = 10_000_000
291 if sc.iterations > maxScramIterations {
292 return fmt.Errorf("SCRAM iteration count from server too high: %d (max %d)", sc.iterations, maxScramIterations)
293 }
294
295 if !bytes.HasPrefix(sc.clientAndServerNonce, sc.clientNonce) {
296 return errors.New("invalid SCRAM nonce: did not start with client nonce")
297 }
298
299 if len(sc.clientAndServerNonce) <= len(sc.clientNonce) {
300 return errors.New("invalid SCRAM nonce: did not include server nonce")
301 }

Calls

no outgoing calls