Пример #1
0
/*
 * Verify a plaintext password against a SCRAM verifier.  This is used when
 * performing plaintext password authentication for a user that has a SCRAM
 * verifier stored in pg_authid.
 */
bool
scram_verify_plain_password(const char *username, const char *password,
							const char *verifier)
{
	char	   *encoded_salt;
	char	   *salt;
	int			saltlen;
	int			iterations;
	uint8		salted_password[SCRAM_KEY_LEN];
	uint8		stored_key[SCRAM_KEY_LEN];
	uint8		server_key[SCRAM_KEY_LEN];
	uint8		computed_key[SCRAM_KEY_LEN];
	char	   *prep_password = NULL;
	pg_saslprep_rc rc;

	if (!parse_scram_verifier(verifier, &iterations, &encoded_salt,
							  stored_key, server_key))
	{
		/*
		 * The password looked like a SCRAM verifier, but could not be parsed.
		 */
		ereport(LOG,
				(errmsg("invalid SCRAM verifier for user \"%s\"", username)));
		return false;
	}

	salt = palloc(pg_b64_dec_len(strlen(encoded_salt)));
	saltlen = pg_b64_decode(encoded_salt, strlen(encoded_salt), salt);
	if (saltlen == -1)
	{
		ereport(LOG,
				(errmsg("invalid SCRAM verifier for user \"%s\"", username)));
		return false;
	}

	/* Normalize the password */
	rc = pg_saslprep(password, &prep_password);
	if (rc == SASLPREP_SUCCESS)
		password = prep_password;

	/* Compute Server Key based on the user-supplied plaintext password */
	scram_SaltedPassword(password, salt, saltlen, iterations, salted_password);
	scram_ServerKey(salted_password, computed_key);

	if (prep_password)
		pfree(prep_password);

	/*
	 * Compare the verifier's Server Key with the one computed from the
	 * user-supplied password.
	 */
	return memcmp(computed_key, server_key, SCRAM_KEY_LEN) == 0;
}
Пример #2
0
/*
 * Calculate ClientKey or ServerKey.
 */
void
scram_ClientOrServerKey(const char *password,
						const char *salt, int saltlen, int iterations,
						const char *keystr, uint8 *result)
{
	uint8		keybuf[SCRAM_KEY_LEN];
	scram_HMAC_ctx ctx;

	scram_SaltedPassword(password, salt, saltlen, iterations, keybuf);
	scram_HMAC_init(&ctx, keybuf, SCRAM_KEY_LEN);
	scram_HMAC_update(&ctx, keystr, strlen(keystr));
	scram_HMAC_final(result, &ctx);
}