@@ -364,6 +364,52 @@ scram_build_verifier(const char *username, const char *password,
364
364
return psprintf ("scram-sha-256:%s:%d:%s:%s" , encoded_salt , iterations , storedkey_hex , serverkey_hex );
365
365
}
366
366
367
+ /*
368
+ * Verify a plaintext password against a SCRAM verifier. This is used when
369
+ * performing plaintext password authentication for a user that has a SCRAM
370
+ * verifier stored in pg_authid.
371
+ */
372
+ bool
373
+ scram_verify_plain_password (const char * username , const char * password ,
374
+ const char * verifier )
375
+ {
376
+ char * encoded_salt ;
377
+ char * salt ;
378
+ int saltlen ;
379
+ int iterations ;
380
+ uint8 stored_key [SCRAM_KEY_LEN ];
381
+ uint8 server_key [SCRAM_KEY_LEN ];
382
+ uint8 computed_key [SCRAM_KEY_LEN ];
383
+
384
+ if (!parse_scram_verifier (verifier , & encoded_salt , & iterations ,
385
+ stored_key , server_key ))
386
+ {
387
+ /*
388
+ * The password looked like a SCRAM verifier, but could not be
389
+ * parsed.
390
+ */
391
+ elog (LOG , "invalid SCRAM verifier for user \"%s\"" , username );
392
+ return false;
393
+ }
394
+
395
+ salt = palloc (pg_b64_dec_len (strlen (encoded_salt )));
396
+ saltlen = pg_b64_decode (encoded_salt , strlen (encoded_salt ), salt );
397
+ if (saltlen == -1 )
398
+ {
399
+ elog (LOG , "invalid SCRAM verifier for user \"%s\"" , username );
400
+ return false;
401
+ }
402
+
403
+ /* Compute Server key based on the user-supplied plaintext password */
404
+ scram_ClientOrServerKey (password , salt , saltlen , iterations ,
405
+ SCRAM_SERVER_KEY_NAME , computed_key );
406
+
407
+ /*
408
+ * Compare the verifier's Server Key with the one computed from the
409
+ * user-supplied password.
410
+ */
411
+ return memcmp (computed_key , server_key , SCRAM_KEY_LEN ) == 0 ;
412
+ }
367
413
368
414
/*
369
415
* Check if given verifier can be used for SCRAM authentication.
0 commit comments