@@ -364,6 +364,52 @@ scram_build_verifier(const char *username, const char *password,
364364 return psprintf ("scram-sha-256:%s:%d:%s:%s" , encoded_salt , iterations , storedkey_hex , serverkey_hex );
365365}
366366
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+ }
367413
368414/*
369415 * Check if given verifier can be used for SCRAM authentication.
0 commit comments