From: Peter Eisentraut <peter.eisentraut@2ndquadrant.com>
To: pgsql-hackers <pgsql-hackers@postgresql.org>
Cc: Heikki Linnakangas <hlinnaka@iki.fi>
Subject: Re: use of the term "verifier" with SCRAM
Date: Thu, 10 Oct 2019 09:08:37 +0200
Message-ID: <73ba767c-f7dc-ce9e-3810-0daa184918a0@2ndquadrant.com> (raw)
In-Reply-To: <fbb1575d-6c68-0bb1-46e8-3df49298963c@iki.fi>
References: <be397b06-6e4b-ba71-c7fb-54cae84a7e18@2ndquadrant.com>
<fbb1575d-6c68-0bb1-46e8-3df49298963c@iki.fi>
On 2019-08-14 10:41, Heikki Linnakangas wrote:
>> RFC 5803 is titled "Lightweight Directory Access Protocol (LDAP) Schema
>> for Storing Salted Challenge Response Authentication Mechanism (SCRAM)
>> Secrets". Following that, I think calling the contents of rolpassword a
>> "secret" or a "stored secret" would be better.
> But I agree that "secret", as used in RFC5803 is better.
Here is my proposed patch to adjust this.
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
From 008f0302bc9821efba84d54dc0f46e62f6047075 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Wed, 9 Oct 2019 10:59:58 +0200
Subject: [PATCH] Fix use of term "verifier"
Within the context of SCRAM, "verifier" has a specific meaning in the
protocol, per RFCs. The existing code used "verifier" differently, to
mean whatever is or would be stored in pg_auth.rolpassword.
Fix this by using the term "secret" for this, following RFC 5803.
---
src/backend/libpq/auth-scram.c | 104 +++++++++++-----------
src/backend/libpq/auth.c | 2 +-
src/backend/libpq/crypt.c | 8 +-
src/common/scram-common.c | 4 +-
src/include/common/scram-common.h | 6 +-
src/include/libpq/crypt.h | 2 +-
src/include/libpq/scram.h | 8 +-
src/interfaces/libpq/fe-auth-scram.c | 6 +-
src/interfaces/libpq/fe-auth.c | 2 +-
src/interfaces/libpq/fe-auth.h | 2 +-
src/test/authentication/t/001_password.pl | 2 +-
src/test/regress/expected/password.out | 12 +--
src/test/regress/sql/password.sql | 12 +--
13 files changed, 85 insertions(+), 85 deletions(-)
diff --git a/src/backend/libpq/auth-scram.c b/src/backend/libpq/auth-scram.cindex 68792cb45e..8ecb17bae6 100644--- a/src/backend/libpq/auth-scram.c+++ b/src/backend/libpq/auth-scram.c@@ -64,10 +64,10 @@
* Don't reveal user information to an unauthenticated client. We don't
* want an attacker to be able to probe whether a particular username is
* valid. In SCRAM, the server has to read the salt and iteration count
- * from the user's password verifier, and send it to the client. To avoid+ * from the user's stored secret, and send it to the client. To avoid
* revealing whether a user exists, when the client tries to authenticate
* with a username that doesn't exist, or doesn't have a valid SCRAM
- * verifier in pg_authid, we create a fake salt and iteration count+ * secret in pg_authid, we create a fake salt and iteration count
* on-the-fly, and proceed with the authentication with that. In the end,
* we'll reject the attempt, as if an incorrect password was given. When
* we are performing a "mock" authentication, the 'doomed' flag in
@@ -161,7 +161,7 @@ static char *build_server_first_message(scram_state *state);
static char *build_server_final_message(scram_state *state);
static bool verify_client_proof(scram_state *state);
static bool verify_final_nonce(scram_state *state);
-static void mock_scram_verifier(const char *username, int *iterations,+static void mock_scram_secret(const char *username, int *iterations,
char **salt, uint8 *stored_key, uint8 *server_key);
static bool is_scram_printable(char *p);
static char *sanitize_char(char c);
@@ -202,13 +202,13 @@ pg_be_scram_get_mechanisms(Port *port, StringInfo buf)
*
* Initialize a new SCRAM authentication exchange status tracker. This
* needs to be called before doing any exchange. It will be filled later
- * after the beginning of the exchange with verifier data.+ * after the beginning of the exchange with authentication information.
*
* 'selected_mech' identifies the SASL mechanism that the client selected.
* It should be one of the mechanisms that we support, as returned by
* pg_be_scram_get_mechanisms().
*
- * 'shadow_pass' is the role's password verifier, from pg_authid.rolpassword.+ * 'shadow_pass' is the role's stored secret, from pg_authid.rolpassword.
* The username was provided by the client in the startup message, and is
* available in port->user_name. If 'shadow_pass' is NULL, we still perform
* an authentication exchange, but it will fail, as if an incorrect password
@@ -220,7 +220,7 @@ pg_be_scram_init(Port *port,
const char *shadow_pass)
{
scram_state *state;
- bool got_verifier;+ bool got_secret;
state = (scram_state *) palloc0(sizeof(scram_state));
state->port = port;
@@ -248,7 +248,7 @@ pg_be_scram_init(Port *port,
errmsg("client selected an invalid SASL authentication mechanism")));
/*
- * Parse the stored password verifier.+ * Parse the stored secret.
*/
if (shadow_pass)
{
@@ -256,30 +256,30 @@ pg_be_scram_init(Port *port,
if (password_type == PASSWORD_TYPE_SCRAM_SHA_256)
{
- if (parse_scram_verifier(shadow_pass, &state->iterations, &state->salt,+ if (parse_scram_secret(shadow_pass, &state->iterations, &state->salt,
state->StoredKey, state->ServerKey))
- got_verifier = true;+ got_secret = true;
else
{
/*
- * The password looked like a SCRAM verifier, but could not be+ * The password looked like a SCRAM secret, but could not be
* parsed.
*/
ereport(LOG,
- (errmsg("invalid SCRAM verifier for user \"%s\"",+ (errmsg("invalid SCRAM secret for user \"%s\"",
state->port->user_name)));
- got_verifier = false;+ got_secret = false;
}
}
else
{
/*
- * The user doesn't have SCRAM verifier. (You cannot do SCRAM+ * The user doesn't have SCRAM secret. (You cannot do SCRAM
* authentication with an MD5 hash.)
*/
- state->logdetail = psprintf(_("User \"%s\" does not have a valid SCRAM verifier."),+ state->logdetail = psprintf(_("User \"%s\" does not have a valid SCRAM secret."),
state->port->user_name);
- got_verifier = false;+ got_secret = false;
}
}
else
@@ -289,18 +289,18 @@ pg_be_scram_init(Port *port,
* considered normal, since the caller requested it, so don't set log
* detail.
*/
- got_verifier = false;+ got_secret = false;
}
/*
- * If the user did not have a valid SCRAM verifier, we still go through+ * If the user did not have a valid SCRAM secret, we still go through
* the motions with a mock one, and fail as if the client supplied an
* incorrect password. This is to avoid revealing information to an
* attacker.
*/
- if (!got_verifier)+ if (!got_secret)
{
- mock_scram_verifier(state->port->user_name, &state->iterations,+ mock_scram_secret(state->port->user_name, &state->iterations,
&state->salt, state->StoredKey, state->ServerKey);
state->doomed = true;
}
@@ -443,12 +443,12 @@ pg_be_scram_exchange(void *opaq, const char *input, int inputlen,
}
/*
- * Construct a verifier string for SCRAM, stored in pg_authid.rolpassword.+ * Construct a SCRAM secret, for storing in pg_authid.rolpassword.
*
* The result is palloc'd, so caller is responsible for freeing it.
*/
char *
-pg_be_scram_build_verifier(const char *password)+pg_be_scram_build_secret(const char *password)
{
char *prep_password;
pg_saslprep_rc rc;
@@ -470,7 +470,7 @@ pg_be_scram_build_verifier(const char *password)
(errcode(ERRCODE_INTERNAL_ERROR),
errmsg("could not generate random salt")));
- result = scram_build_verifier(saltbuf, SCRAM_DEFAULT_SALT_LEN,+ result = scram_build_secret(saltbuf, SCRAM_DEFAULT_SALT_LEN,
SCRAM_DEFAULT_ITERATIONS, password);
if (prep_password)
@@ -480,13 +480,13 @@ pg_be_scram_build_verifier(const char *password)
}
/*
- * Verify a plaintext password against a SCRAM verifier. This is used when+ * Verify a plaintext password against a SCRAM secret. This is used when
* performing plaintext password authentication for a user that has a SCRAM
- * verifier stored in pg_authid.+ * secret stored in pg_authid.
*/
bool
scram_verify_plain_password(const char *username, const char *password,
- const char *verifier)+ const char *secret)
{
char *encoded_salt;
char *salt;
@@ -499,14 +499,14 @@ scram_verify_plain_password(const char *username, const char *password,
char *prep_password;
pg_saslprep_rc rc;
- if (!parse_scram_verifier(verifier, &iterations, &encoded_salt,+ if (!parse_scram_secret(secret, &iterations, &encoded_salt,
stored_key, server_key))
{
/*
- * The password looked like a SCRAM verifier, but could not be parsed.+ * The password looked like a SCRAM secret, but could not be parsed.
*/
ereport(LOG,
- (errmsg("invalid SCRAM verifier for user \"%s\"", username)));+ (errmsg("invalid SCRAM secret for user \"%s\"", username)));
return false;
}
@@ -517,7 +517,7 @@ scram_verify_plain_password(const char *username, const char *password,
if (saltlen < 0)
{
ereport(LOG,
- (errmsg("invalid SCRAM verifier for user \"%s\"", username)));+ (errmsg("invalid SCRAM secret for user \"%s\"", username)));
return false;
}
@@ -534,7 +534,7 @@ scram_verify_plain_password(const char *username, const char *password,
pfree(prep_password);
/*
- * Compare the verifier's Server Key with the one computed from the+ * Compare the secret's Server Key with the one computed from the
* user-supplied password.
*/
return memcmp(computed_key, server_key, SCRAM_KEY_LEN) == 0;
@@ -542,18 +542,18 @@ scram_verify_plain_password(const char *username, const char *password,
/*
- * Parse and validate format of given SCRAM verifier.+ * Parse and validate format of given SCRAM secret.
*
* On success, the iteration count, salt, stored key, and server key are
- * extracted from the verifier, and returned to the caller. For 'stored_key'+ * extracted from the secret, and returned to the caller. For 'stored_key'
* and 'server_key', the caller must pass pre-allocated buffers of size
* SCRAM_KEY_LEN. Salt is returned as a base64-encoded, null-terminated
* string. The buffer for the salt is palloc'd by this function.
*
- * Returns true if the SCRAM verifier has been parsed, and false otherwise.+ * Returns true if the SCRAM secret has been parsed, and false otherwise.
*/
bool
-parse_scram_verifier(const char *verifier, int *iterations, char **salt,+parse_scram_secret(const char *secret, int *iterations, char **salt,
uint8 *stored_key, uint8 *server_key)
{
char *v;
@@ -569,30 +569,30 @@ parse_scram_verifier(const char *verifier, int *iterations, char **salt,
char *decoded_server_buf;
/*
- * The verifier is of form:+ * The secret is of form:
*
* SCRAM-SHA-256$<iterations>:<salt>$<storedkey>:<serverkey>
*/
- v = pstrdup(verifier);+ v = pstrdup(secret);
if ((scheme_str = strtok(v, "$")) == NULL)
- goto invalid_verifier;+ goto invalid_secret;
if ((iterations_str = strtok(NULL, ":")) == NULL)
- goto invalid_verifier;+ goto invalid_secret;
if ((salt_str = strtok(NULL, "$")) == NULL)
- goto invalid_verifier;+ goto invalid_secret;
if ((storedkey_str = strtok(NULL, ":")) == NULL)
- goto invalid_verifier;+ goto invalid_secret;
if ((serverkey_str = strtok(NULL, "")) == NULL)
- goto invalid_verifier;+ goto invalid_secret;
/* Parse the fields */
if (strcmp(scheme_str, "SCRAM-SHA-256") != 0)
- goto invalid_verifier;+ goto invalid_secret;
errno = 0;
*iterations = strtol(iterations_str, &p, 10);
if (*p || errno != 0)
- goto invalid_verifier;+ goto invalid_secret;
/*
* Verify that the salt is in Base64-encoded format, by decoding it,
@@ -603,7 +603,7 @@ parse_scram_verifier(const char *verifier, int *iterations, char **salt,
decoded_len = pg_b64_decode(salt_str, strlen(salt_str),
decoded_salt_buf, decoded_len);
if (decoded_len < 0)
- goto invalid_verifier;+ goto invalid_secret;
*salt = pstrdup(salt_str);
/*
@@ -614,7 +614,7 @@ parse_scram_verifier(const char *verifier, int *iterations, char **salt,
decoded_len = pg_b64_decode(storedkey_str, strlen(storedkey_str),
decoded_stored_buf, decoded_len);
if (decoded_len != SCRAM_KEY_LEN)
- goto invalid_verifier;+ goto invalid_secret;
memcpy(stored_key, decoded_stored_buf, SCRAM_KEY_LEN);
decoded_len = pg_b64_dec_len(strlen(serverkey_str));
@@ -622,29 +622,29 @@ parse_scram_verifier(const char *verifier, int *iterations, char **salt,
decoded_len = pg_b64_decode(serverkey_str, strlen(serverkey_str),
decoded_server_buf, decoded_len);
if (decoded_len != SCRAM_KEY_LEN)
- goto invalid_verifier;+ goto invalid_secret;
memcpy(server_key, decoded_server_buf, SCRAM_KEY_LEN);
return true;
-invalid_verifier:+invalid_secret:
*salt = NULL;
return false;
}
/*
- * Generate plausible SCRAM verifier parameters for mock authentication.+ * Generate plausible SCRAM secret parameters for mock authentication.
*
- * In a normal authentication, these are extracted from the verifier+ * In a normal authentication, these are extracted from the secret
* stored in the server. This function generates values that look
- * realistic, for when there is no stored verifier.+ * realistic, for when there is no stored secret.
*
- * Like in parse_scram_verifier(), for 'stored_key' and 'server_key', the+ * Like in parse_scram_secret(), for 'stored_key' and 'server_key', the
* caller must pass pre-allocated buffers of size SCRAM_KEY_LEN, and
* the buffer for the salt is palloc'd by this function.
*/
static void
-mock_scram_verifier(const char *username, int *iterations, char **salt,+mock_scram_secret(const char *username, int *iterations, char **salt,
uint8 *stored_key, uint8 *server_key)
{
char *raw_salt;
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.cindex 3ef0171192..0cf65ba5de 100644--- a/src/backend/libpq/auth.c+++ b/src/backend/libpq/auth.c@@ -818,7 +818,7 @@ CheckPWChallengeAuth(Port *port, char **logdetail)
* If 'md5' authentication is allowed, decide whether to perform 'md5' or
* 'scram-sha-256' authentication based on the type of password the user
* has. If it's an MD5 hash, we must do MD5 authentication, and if it's a
- * SCRAM verifier, we must do SCRAM authentication.+ * SCRAM secret, we must do SCRAM authentication.
*
* If MD5 authentication is not allowed, always use SCRAM. If the user
* had an MD5 password, CheckSCRAMAuth() will fail.
diff --git a/src/backend/libpq/crypt.c b/src/backend/libpq/crypt.cindex 784fb227aa..9add6a14b2 100644--- a/src/backend/libpq/crypt.c+++ b/src/backend/libpq/crypt.c@@ -83,7 +83,7 @@ get_role_password(const char *role, char **logdetail)
}
/*
- * What kind of a password verifier is 'shadow_pass'?+ * What kind of a password type is 'shadow_pass'?
*/
PasswordType
get_password_type(const char *shadow_pass)
@@ -97,14 +97,14 @@ get_password_type(const char *shadow_pass)
strlen(shadow_pass) == MD5_PASSWD_LEN &&
strspn(shadow_pass + 3, MD5_PASSWD_CHARSET) == MD5_PASSWD_LEN - 3)
return PASSWORD_TYPE_MD5;
- if (parse_scram_verifier(shadow_pass, &iterations, &encoded_salt,+ if (parse_scram_secret(shadow_pass, &iterations, &encoded_salt,
stored_key, server_key))
return PASSWORD_TYPE_SCRAM_SHA_256;
return PASSWORD_TYPE_PLAINTEXT;
}
/*
- * Given a user-supplied password, convert it into a verifier of+ * Given a user-supplied password, convert it into a secret of
* 'target_type' kind.
*
* If the password is already in encrypted form, we cannot reverse the
@@ -137,7 +137,7 @@ encrypt_password(PasswordType target_type, const char *role,
return encrypted_password;
case PASSWORD_TYPE_SCRAM_SHA_256:
- return pg_be_scram_build_verifier(password);+ return pg_be_scram_build_secret(password);
case PASSWORD_TYPE_PLAINTEXT:
elog(ERROR, "cannot encrypt password with 'plaintext'");
diff --git a/src/common/scram-common.c b/src/common/scram-common.cindex dff9723e67..72bfa38a2e 100644--- a/src/common/scram-common.c+++ b/src/common/scram-common.c@@ -181,7 +181,7 @@ scram_ServerKey(const uint8 *salted_password, uint8 *result)
/*
- * Construct a verifier string for SCRAM, stored in pg_authid.rolpassword.+ * Construct a SCRAM secret, for storing in pg_authid.rolpassword.
*
* The password should already have been processed with SASLprep, if necessary!
*
@@ -189,7 +189,7 @@ scram_ServerKey(const uint8 *salted_password, uint8 *result)
* palloc'd or malloc'd, so caller is responsible for freeing it.
*/
char *
-scram_build_verifier(const char *salt, int saltlen, int iterations,+scram_build_secret(const char *salt, int saltlen, int iterations,
const char *password)
{
uint8 salted_password[SCRAM_KEY_LEN];
diff --git a/src/include/common/scram-common.h b/src/include/common/scram-common.hindex d52df67ec8..1c46dee58c 100644--- a/src/include/common/scram-common.h+++ b/src/include/common/scram-common.h@@ -33,14 +33,14 @@
#define SCRAM_RAW_NONCE_LEN 18
/*
- * Length of salt when generating new verifiers, in bytes. (It will be stored+ * Length of salt when generating new secrets, in bytes. (It will be stored
* and sent over the wire encoded in Base64.) 16 bytes is what the example in
* RFC 7677 uses.
*/
#define SCRAM_DEFAULT_SALT_LEN 16
/*
- * Default number of iterations when generating verifier. Should be at least+ * Default number of iterations when generating secret. Should be at least
* 4096 per RFC 7677.
*/
#define SCRAM_DEFAULT_ITERATIONS 4096
@@ -64,7 +64,7 @@ extern void scram_H(const uint8 *str, int len, uint8 *result);
extern void scram_ClientKey(const uint8 *salted_password, uint8 *result);
extern void scram_ServerKey(const uint8 *salted_password, uint8 *result);
-extern char *scram_build_verifier(const char *salt, int saltlen, int iterations,+extern char *scram_build_secret(const char *salt, int saltlen, int iterations,
const char *password);
#endif /* SCRAM_COMMON_H */
diff --git a/src/include/libpq/crypt.h b/src/include/libpq/crypt.hindex e6b50a7288..3564ef39d8 100644--- a/src/include/libpq/crypt.h+++ b/src/include/libpq/crypt.h@@ -16,7 +16,7 @@
#include "datatype/timestamp.h"
/*
- * Types of password hashes or verifiers.+ * Types of password hashes or secrets.
*
* Plaintext passwords can be passed in by the user, in a CREATE/ALTER USER
* command. They will be encrypted to MD5 or SCRAM-SHA-256 format, before
diff --git a/src/include/libpq/scram.h b/src/include/libpq/scram.hindex 87e2d56301..71fcb51c5a 100644--- a/src/include/libpq/scram.h+++ b/src/include/libpq/scram.h@@ -27,11 +27,11 @@ extern void *pg_be_scram_init(Port *port, const char *selected_mech, const char
extern int pg_be_scram_exchange(void *opaq, const char *input, int inputlen,
char **output, int *outputlen, char **logdetail);
-/* Routines to handle and check SCRAM-SHA-256 verifier */-extern char *pg_be_scram_build_verifier(const char *password);-extern bool parse_scram_verifier(const char *verifier, int *iterations, char **salt,+/* Routines to handle and check SCRAM-SHA-256 secret */+extern char *pg_be_scram_build_secret(const char *password);+extern bool parse_scram_secret(const char *secret, int *iterations, char **salt,
uint8 *stored_key, uint8 *server_key);
extern bool scram_verify_plain_password(const char *username,
- const char *password, const char *verifier);+ const char *password, const char *secret);
#endif /* PG_SCRAM_H */
diff --git a/src/interfaces/libpq/fe-auth-scram.c b/src/interfaces/libpq/fe-auth-scram.cindex 693739c544..741f566a72 100644--- a/src/interfaces/libpq/fe-auth-scram.c+++ b/src/interfaces/libpq/fe-auth-scram.c@@ -822,10 +822,10 @@ verify_server_signature(fe_scram_state *state)
}
/*
- * Build a new SCRAM verifier.+ * Build a new SCRAM secret.
*/
char *
-pg_fe_scram_build_verifier(const char *password)+pg_fe_scram_build_secret(const char *password)
{
char *prep_password;
pg_saslprep_rc rc;
@@ -851,7 +851,7 @@ pg_fe_scram_build_verifier(const char *password)
return NULL;
}
- result = scram_build_verifier(saltbuf, SCRAM_DEFAULT_SALT_LEN,+ result = scram_build_secret(saltbuf, SCRAM_DEFAULT_SALT_LEN,
SCRAM_DEFAULT_ITERATIONS, password);
if (prep_password)
diff --git a/src/interfaces/libpq/fe-auth.c b/src/interfaces/libpq/fe-auth.cindex 8ca7b39326..a690f3ba3a 100644--- a/src/interfaces/libpq/fe-auth.c+++ b/src/interfaces/libpq/fe-auth.c@@ -1251,7 +1251,7 @@ PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user,
*/
if (strcmp(algorithm, "scram-sha-256") == 0)
{
- crypt_pwd = pg_fe_scram_build_verifier(passwd);+ crypt_pwd = pg_fe_scram_build_secret(passwd);
}
else if (strcmp(algorithm, "md5") == 0)
{
diff --git a/src/interfaces/libpq/fe-auth.h b/src/interfaces/libpq/fe-auth.hindex 2f1af53fb0..3d3db41f8c 100644--- a/src/interfaces/libpq/fe-auth.h+++ b/src/interfaces/libpq/fe-auth.h@@ -31,6 +31,6 @@ extern void pg_fe_scram_free(void *opaq);
extern void pg_fe_scram_exchange(void *opaq, char *input, int inputlen,
char **output, int *outputlen,
bool *done, bool *success);
-extern char *pg_fe_scram_build_verifier(const char *password);+extern char *pg_fe_scram_build_secret(const char *password);
#endif /* FE_AUTH_H */
diff --git a/src/test/authentication/t/001_password.pl b/src/test/authentication/t/001_password.plindex aae6de8b34..5985130e3d 100644--- a/src/test/authentication/t/001_password.pl+++ b/src/test/authentication/t/001_password.pl@@ -82,7 +82,7 @@ sub test_role
test_role($node, 'md5_role', 'scram-sha-256', 2);
# For "md5" method, all users should be able to connect (SCRAM
-# authentication will be performed for the user with a scram verifier.)+# authentication will be performed for the user with a SCRAM secret.)
reset_pg_hba($node, 'md5');
test_role($node, 'scram_role', 'md5', 0);
test_role($node, 'md5_role', 'md5', 0);
diff --git a/src/test/regress/expected/password.out b/src/test/regress/expected/password.outindex f1ae34f15f..2b852aa324 100644--- a/src/test/regress/expected/password.out+++ b/src/test/regress/expected/password.out@@ -1,5 +1,5 @@
--
--- Tests for password verifiers+-- Tests for password types
--
-- Tests for GUC password_encryption
SET password_encryption = 'novalue'; -- error
@@ -18,7 +18,7 @@ CREATE ROLE regress_passwd3 PASSWORD 'role_pwd3';
CREATE ROLE regress_passwd4 PASSWORD NULL;
-- check list of created entries
--
--- The scram verifier will look something like:+-- The scram secret will look something like:
-- SCRAM-SHA-256$4096:E4HxLGtnRzsYwg==$6YtlR4t69SguDiwFvbVgVZtuz6gpJQQqUMZ7IQJK5yI=:ps75jrHeYU4lXCcXI4O8oIdJ3eO8o2jirjruw9phBTo=
--
-- Since the salt is random, the exact value stored will be different on every test
@@ -58,14 +58,14 @@ ALTER ROLE regress_passwd2 PASSWORD 'foo';
ALTER ROLE regress_passwd1 PASSWORD 'md5cd3578025fe2c3d7ed1b9a9b26238b70';
ALTER ROLE regress_passwd3 PASSWORD 'SCRAM-SHA-256$4096:VLK4RMaQLCvNtQ==$6YtlR4t69SguDiwFvbVgVZtuz6gpJQQqUMZ7IQJK5yI=:ps75jrHeYU4lXCcXI4O8oIdJ3eO8o2jirjruw9phBTo=';
SET password_encryption = 'scram-sha-256';
--- create SCRAM verifier+-- create SCRAM secret
ALTER ROLE regress_passwd4 PASSWORD 'foo';
-- already encrypted with MD5, use as it is
CREATE ROLE regress_passwd5 PASSWORD 'md5e73a4b11df52a6068f8b39f90be36023';
--- This looks like a valid SCRAM-SHA-256 verifier, but it is not+-- This looks like a valid SCRAM-SHA-256 secret, but it is not
-- so it should be hashed with SCRAM-SHA-256.
CREATE ROLE regress_passwd6 PASSWORD 'SCRAM-SHA-256$1234';
--- These may look like valid MD5 verifiers, but they are not, so they+-- These may look like valid MD5 secrets, but they are not, so they
-- should be hashed with SCRAM-SHA-256.
-- trailing garbage at the end
CREATE ROLE regress_passwd7 PASSWORD 'md5012345678901234567890123456789zz';
@@ -107,7 +107,7 @@ SELECT rolpassword FROM pg_authid WHERE rolname='regress_passwd_empty';
CREATE ROLE regress_passwd_sha_len0 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96Rqw=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZI=';
CREATE ROLE regress_passwd_sha_len1 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96RqwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZI=';
CREATE ROLE regress_passwd_sha_len2 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96Rqw=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=';
--- Check that the invalid verifiers were re-hashed. A re-hashed verifier+-- Check that the invalid secrets were re-hashed. A re-hashed secret
-- should not contain the original salt.
SELECT rolname, rolpassword not like '%A6xHKoH/494E941doaPOYg==%' as is_rolpassword_rehashed
FROM pg_authid
diff --git a/src/test/regress/sql/password.sql b/src/test/regress/sql/password.sqlindex fad88ba689..1e7e19eafa 100644--- a/src/test/regress/sql/password.sql+++ b/src/test/regress/sql/password.sql@@ -1,5 +1,5 @@
--
--- Tests for password verifiers+-- Tests for password types
--
-- Tests for GUC password_encryption
@@ -19,7 +19,7 @@ CREATE ROLE regress_passwd4 PASSWORD NULL;
-- check list of created entries
--
--- The scram verifier will look something like:+-- The scram secret will look something like:
-- SCRAM-SHA-256$4096:E4HxLGtnRzsYwg==$6YtlR4t69SguDiwFvbVgVZtuz6gpJQQqUMZ7IQJK5yI=:ps75jrHeYU4lXCcXI4O8oIdJ3eO8o2jirjruw9phBTo=
--
-- Since the salt is random, the exact value stored will be different on every test
@@ -49,15 +49,15 @@ CREATE ROLE regress_passwd4 PASSWORD NULL;
ALTER ROLE regress_passwd3 PASSWORD 'SCRAM-SHA-256$4096:VLK4RMaQLCvNtQ==$6YtlR4t69SguDiwFvbVgVZtuz6gpJQQqUMZ7IQJK5yI=:ps75jrHeYU4lXCcXI4O8oIdJ3eO8o2jirjruw9phBTo=';
SET password_encryption = 'scram-sha-256';
--- create SCRAM verifier+-- create SCRAM secret
ALTER ROLE regress_passwd4 PASSWORD 'foo';
-- already encrypted with MD5, use as it is
CREATE ROLE regress_passwd5 PASSWORD 'md5e73a4b11df52a6068f8b39f90be36023';
--- This looks like a valid SCRAM-SHA-256 verifier, but it is not+-- This looks like a valid SCRAM-SHA-256 secret, but it is not
-- so it should be hashed with SCRAM-SHA-256.
CREATE ROLE regress_passwd6 PASSWORD 'SCRAM-SHA-256$1234';
--- These may look like valid MD5 verifiers, but they are not, so they+-- These may look like valid MD5 secrets, but they are not, so they
-- should be hashed with SCRAM-SHA-256.
-- trailing garbage at the end
CREATE ROLE regress_passwd7 PASSWORD 'md5012345678901234567890123456789zz';
@@ -83,7 +83,7 @@ CREATE ROLE regress_passwd_sha_len0 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941
CREATE ROLE regress_passwd_sha_len1 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96RqwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZI=';
CREATE ROLE regress_passwd_sha_len2 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96Rqw=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=';
--- Check that the invalid verifiers were re-hashed. A re-hashed verifier+-- Check that the invalid secrets were re-hashed. A re-hashed secret
-- should not contain the original salt.
SELECT rolname, rolpassword not like '%A6xHKoH/494E941doaPOYg==%' as is_rolpassword_rehashed
FROM pg_authid
--
2.23.0
Attachments:
[text/plain] 0001-Fix-use-of-term-verifier.patch (26.6K, ../73ba767c-f7dc-ce9e-3810-0daa184918a0@2ndquadrant.com/2-0001-Fix-use-of-term-verifier.patch)
download | inline diff:
From 008f0302bc9821efba84d54dc0f46e62f6047075 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Wed, 9 Oct 2019 10:59:58 +0200
Subject: [PATCH] Fix use of term "verifier"
Within the context of SCRAM, "verifier" has a specific meaning in the
protocol, per RFCs. The existing code used "verifier" differently, to
mean whatever is or would be stored in pg_auth.rolpassword.
Fix this by using the term "secret" for this, following RFC 5803.
---
src/backend/libpq/auth-scram.c | 104 +++++++++++-----------
src/backend/libpq/auth.c | 2 +-
src/backend/libpq/crypt.c | 8 +-
src/common/scram-common.c | 4 +-
src/include/common/scram-common.h | 6 +-
src/include/libpq/crypt.h | 2 +-
src/include/libpq/scram.h | 8 +-
src/interfaces/libpq/fe-auth-scram.c | 6 +-
src/interfaces/libpq/fe-auth.c | 2 +-
src/interfaces/libpq/fe-auth.h | 2 +-
src/test/authentication/t/001_password.pl | 2 +-
src/test/regress/expected/password.out | 12 +--
src/test/regress/sql/password.sql | 12 +--
13 files changed, 85 insertions(+), 85 deletions(-)
diff --git a/src/backend/libpq/auth-scram.c b/src/backend/libpq/auth-scram.cindex 68792cb45e..8ecb17bae6 100644--- a/src/backend/libpq/auth-scram.c+++ b/src/backend/libpq/auth-scram.c@@ -64,10 +64,10 @@
* Don't reveal user information to an unauthenticated client. We don't
* want an attacker to be able to probe whether a particular username is
* valid. In SCRAM, the server has to read the salt and iteration count
- * from the user's password verifier, and send it to the client. To avoid+ * from the user's stored secret, and send it to the client. To avoid
* revealing whether a user exists, when the client tries to authenticate
* with a username that doesn't exist, or doesn't have a valid SCRAM
- * verifier in pg_authid, we create a fake salt and iteration count+ * secret in pg_authid, we create a fake salt and iteration count
* on-the-fly, and proceed with the authentication with that. In the end,
* we'll reject the attempt, as if an incorrect password was given. When
* we are performing a "mock" authentication, the 'doomed' flag in
@@ -161,7 +161,7 @@ static char *build_server_first_message(scram_state *state);
static char *build_server_final_message(scram_state *state);
static bool verify_client_proof(scram_state *state);
static bool verify_final_nonce(scram_state *state);
-static void mock_scram_verifier(const char *username, int *iterations,+static void mock_scram_secret(const char *username, int *iterations,
char **salt, uint8 *stored_key, uint8 *server_key);
static bool is_scram_printable(char *p);
static char *sanitize_char(char c);
@@ -202,13 +202,13 @@ pg_be_scram_get_mechanisms(Port *port, StringInfo buf)
*
* Initialize a new SCRAM authentication exchange status tracker. This
* needs to be called before doing any exchange. It will be filled later
- * after the beginning of the exchange with verifier data.+ * after the beginning of the exchange with authentication information.
*
* 'selected_mech' identifies the SASL mechanism that the client selected.
* It should be one of the mechanisms that we support, as returned by
* pg_be_scram_get_mechanisms().
*
- * 'shadow_pass' is the role's password verifier, from pg_authid.rolpassword.+ * 'shadow_pass' is the role's stored secret, from pg_authid.rolpassword.
* The username was provided by the client in the startup message, and is
* available in port->user_name. If 'shadow_pass' is NULL, we still perform
* an authentication exchange, but it will fail, as if an incorrect password
@@ -220,7 +220,7 @@ pg_be_scram_init(Port *port,
const char *shadow_pass)
{
scram_state *state;
- bool got_verifier;+ bool got_secret;
state = (scram_state *) palloc0(sizeof(scram_state));
state->port = port;
@@ -248,7 +248,7 @@ pg_be_scram_init(Port *port,
errmsg("client selected an invalid SASL authentication mechanism")));
/*
- * Parse the stored password verifier.+ * Parse the stored secret.
*/
if (shadow_pass)
{
@@ -256,30 +256,30 @@ pg_be_scram_init(Port *port,
if (password_type == PASSWORD_TYPE_SCRAM_SHA_256)
{
- if (parse_scram_verifier(shadow_pass, &state->iterations, &state->salt,+ if (parse_scram_secret(shadow_pass, &state->iterations, &state->salt,
state->StoredKey, state->ServerKey))
- got_verifier = true;+ got_secret = true;
else
{
/*
- * The password looked like a SCRAM verifier, but could not be+ * The password looked like a SCRAM secret, but could not be
* parsed.
*/
ereport(LOG,
- (errmsg("invalid SCRAM verifier for user \"%s\"",+ (errmsg("invalid SCRAM secret for user \"%s\"",
state->port->user_name)));
- got_verifier = false;+ got_secret = false;
}
}
else
{
/*
- * The user doesn't have SCRAM verifier. (You cannot do SCRAM+ * The user doesn't have SCRAM secret. (You cannot do SCRAM
* authentication with an MD5 hash.)
*/
- state->logdetail = psprintf(_("User \"%s\" does not have a valid SCRAM verifier."),+ state->logdetail = psprintf(_("User \"%s\" does not have a valid SCRAM secret."),
state->port->user_name);
- got_verifier = false;+ got_secret = false;
}
}
else
@@ -289,18 +289,18 @@ pg_be_scram_init(Port *port,
* considered normal, since the caller requested it, so don't set log
* detail.
*/
- got_verifier = false;+ got_secret = false;
}
/*
- * If the user did not have a valid SCRAM verifier, we still go through+ * If the user did not have a valid SCRAM secret, we still go through
* the motions with a mock one, and fail as if the client supplied an
* incorrect password. This is to avoid revealing information to an
* attacker.
*/
- if (!got_verifier)+ if (!got_secret)
{
- mock_scram_verifier(state->port->user_name, &state->iterations,+ mock_scram_secret(state->port->user_name, &state->iterations,
&state->salt, state->StoredKey, state->ServerKey);
state->doomed = true;
}
@@ -443,12 +443,12 @@ pg_be_scram_exchange(void *opaq, const char *input, int inputlen,
}
/*
- * Construct a verifier string for SCRAM, stored in pg_authid.rolpassword.+ * Construct a SCRAM secret, for storing in pg_authid.rolpassword.
*
* The result is palloc'd, so caller is responsible for freeing it.
*/
char *
-pg_be_scram_build_verifier(const char *password)+pg_be_scram_build_secret(const char *password)
{
char *prep_password;
pg_saslprep_rc rc;
@@ -470,7 +470,7 @@ pg_be_scram_build_verifier(const char *password)
(errcode(ERRCODE_INTERNAL_ERROR),
errmsg("could not generate random salt")));
- result = scram_build_verifier(saltbuf, SCRAM_DEFAULT_SALT_LEN,+ result = scram_build_secret(saltbuf, SCRAM_DEFAULT_SALT_LEN,
SCRAM_DEFAULT_ITERATIONS, password);
if (prep_password)
@@ -480,13 +480,13 @@ pg_be_scram_build_verifier(const char *password)
}
/*
- * Verify a plaintext password against a SCRAM verifier. This is used when+ * Verify a plaintext password against a SCRAM secret. This is used when
* performing plaintext password authentication for a user that has a SCRAM
- * verifier stored in pg_authid.+ * secret stored in pg_authid.
*/
bool
scram_verify_plain_password(const char *username, const char *password,
- const char *verifier)+ const char *secret)
{
char *encoded_salt;
char *salt;
@@ -499,14 +499,14 @@ scram_verify_plain_password(const char *username, const char *password,
char *prep_password;
pg_saslprep_rc rc;
- if (!parse_scram_verifier(verifier, &iterations, &encoded_salt,+ if (!parse_scram_secret(secret, &iterations, &encoded_salt,
stored_key, server_key))
{
/*
- * The password looked like a SCRAM verifier, but could not be parsed.+ * The password looked like a SCRAM secret, but could not be parsed.
*/
ereport(LOG,
- (errmsg("invalid SCRAM verifier for user \"%s\"", username)));+ (errmsg("invalid SCRAM secret for user \"%s\"", username)));
return false;
}
@@ -517,7 +517,7 @@ scram_verify_plain_password(const char *username, const char *password,
if (saltlen < 0)
{
ereport(LOG,
- (errmsg("invalid SCRAM verifier for user \"%s\"", username)));+ (errmsg("invalid SCRAM secret for user \"%s\"", username)));
return false;
}
@@ -534,7 +534,7 @@ scram_verify_plain_password(const char *username, const char *password,
pfree(prep_password);
/*
- * Compare the verifier's Server Key with the one computed from the+ * Compare the secret's Server Key with the one computed from the
* user-supplied password.
*/
return memcmp(computed_key, server_key, SCRAM_KEY_LEN) == 0;
@@ -542,18 +542,18 @@ scram_verify_plain_password(const char *username, const char *password,
/*
- * Parse and validate format of given SCRAM verifier.+ * Parse and validate format of given SCRAM secret.
*
* On success, the iteration count, salt, stored key, and server key are
- * extracted from the verifier, and returned to the caller. For 'stored_key'+ * extracted from the secret, and returned to the caller. For 'stored_key'
* and 'server_key', the caller must pass pre-allocated buffers of size
* SCRAM_KEY_LEN. Salt is returned as a base64-encoded, null-terminated
* string. The buffer for the salt is palloc'd by this function.
*
- * Returns true if the SCRAM verifier has been parsed, and false otherwise.+ * Returns true if the SCRAM secret has been parsed, and false otherwise.
*/
bool
-parse_scram_verifier(const char *verifier, int *iterations, char **salt,+parse_scram_secret(const char *secret, int *iterations, char **salt,
uint8 *stored_key, uint8 *server_key)
{
char *v;
@@ -569,30 +569,30 @@ parse_scram_verifier(const char *verifier, int *iterations, char **salt,
char *decoded_server_buf;
/*
- * The verifier is of form:+ * The secret is of form:
*
* SCRAM-SHA-256$<iterations>:<salt>$<storedkey>:<serverkey>
*/
- v = pstrdup(verifier);+ v = pstrdup(secret);
if ((scheme_str = strtok(v, "$")) == NULL)
- goto invalid_verifier;+ goto invalid_secret;
if ((iterations_str = strtok(NULL, ":")) == NULL)
- goto invalid_verifier;+ goto invalid_secret;
if ((salt_str = strtok(NULL, "$")) == NULL)
- goto invalid_verifier;+ goto invalid_secret;
if ((storedkey_str = strtok(NULL, ":")) == NULL)
- goto invalid_verifier;+ goto invalid_secret;
if ((serverkey_str = strtok(NULL, "")) == NULL)
- goto invalid_verifier;+ goto invalid_secret;
/* Parse the fields */
if (strcmp(scheme_str, "SCRAM-SHA-256") != 0)
- goto invalid_verifier;+ goto invalid_secret;
errno = 0;
*iterations = strtol(iterations_str, &p, 10);
if (*p || errno != 0)
- goto invalid_verifier;+ goto invalid_secret;
/*
* Verify that the salt is in Base64-encoded format, by decoding it,
@@ -603,7 +603,7 @@ parse_scram_verifier(const char *verifier, int *iterations, char **salt,
decoded_len = pg_b64_decode(salt_str, strlen(salt_str),
decoded_salt_buf, decoded_len);
if (decoded_len < 0)
- goto invalid_verifier;+ goto invalid_secret;
*salt = pstrdup(salt_str);
/*
@@ -614,7 +614,7 @@ parse_scram_verifier(const char *verifier, int *iterations, char **salt,
decoded_len = pg_b64_decode(storedkey_str, strlen(storedkey_str),
decoded_stored_buf, decoded_len);
if (decoded_len != SCRAM_KEY_LEN)
- goto invalid_verifier;+ goto invalid_secret;
memcpy(stored_key, decoded_stored_buf, SCRAM_KEY_LEN);
decoded_len = pg_b64_dec_len(strlen(serverkey_str));
@@ -622,29 +622,29 @@ parse_scram_verifier(const char *verifier, int *iterations, char **salt,
decoded_len = pg_b64_decode(serverkey_str, strlen(serverkey_str),
decoded_server_buf, decoded_len);
if (decoded_len != SCRAM_KEY_LEN)
- goto invalid_verifier;+ goto invalid_secret;
memcpy(server_key, decoded_server_buf, SCRAM_KEY_LEN);
return true;
-invalid_verifier:+invalid_secret:
*salt = NULL;
return false;
}
/*
- * Generate plausible SCRAM verifier parameters for mock authentication.+ * Generate plausible SCRAM secret parameters for mock authentication.
*
- * In a normal authentication, these are extracted from the verifier+ * In a normal authentication, these are extracted from the secret
* stored in the server. This function generates values that look
- * realistic, for when there is no stored verifier.+ * realistic, for when there is no stored secret.
*
- * Like in parse_scram_verifier(), for 'stored_key' and 'server_key', the+ * Like in parse_scram_secret(), for 'stored_key' and 'server_key', the
* caller must pass pre-allocated buffers of size SCRAM_KEY_LEN, and
* the buffer for the salt is palloc'd by this function.
*/
static void
-mock_scram_verifier(const char *username, int *iterations, char **salt,+mock_scram_secret(const char *username, int *iterations, char **salt,
uint8 *stored_key, uint8 *server_key)
{
char *raw_salt;
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.cindex 3ef0171192..0cf65ba5de 100644--- a/src/backend/libpq/auth.c+++ b/src/backend/libpq/auth.c@@ -818,7 +818,7 @@ CheckPWChallengeAuth(Port *port, char **logdetail)
* If 'md5' authentication is allowed, decide whether to perform 'md5' or
* 'scram-sha-256' authentication based on the type of password the user
* has. If it's an MD5 hash, we must do MD5 authentication, and if it's a
- * SCRAM verifier, we must do SCRAM authentication.+ * SCRAM secret, we must do SCRAM authentication.
*
* If MD5 authentication is not allowed, always use SCRAM. If the user
* had an MD5 password, CheckSCRAMAuth() will fail.
diff --git a/src/backend/libpq/crypt.c b/src/backend/libpq/crypt.cindex 784fb227aa..9add6a14b2 100644--- a/src/backend/libpq/crypt.c+++ b/src/backend/libpq/crypt.c@@ -83,7 +83,7 @@ get_role_password(const char *role, char **logdetail)
}
/*
- * What kind of a password verifier is 'shadow_pass'?+ * What kind of a password type is 'shadow_pass'?
*/
PasswordType
get_password_type(const char *shadow_pass)
@@ -97,14 +97,14 @@ get_password_type(const char *shadow_pass)
strlen(shadow_pass) == MD5_PASSWD_LEN &&
strspn(shadow_pass + 3, MD5_PASSWD_CHARSET) == MD5_PASSWD_LEN - 3)
return PASSWORD_TYPE_MD5;
- if (parse_scram_verifier(shadow_pass, &iterations, &encoded_salt,+ if (parse_scram_secret(shadow_pass, &iterations, &encoded_salt,
stored_key, server_key))
return PASSWORD_TYPE_SCRAM_SHA_256;
return PASSWORD_TYPE_PLAINTEXT;
}
/*
- * Given a user-supplied password, convert it into a verifier of+ * Given a user-supplied password, convert it into a secret of
* 'target_type' kind.
*
* If the password is already in encrypted form, we cannot reverse the
@@ -137,7 +137,7 @@ encrypt_password(PasswordType target_type, const char *role,
return encrypted_password;
case PASSWORD_TYPE_SCRAM_SHA_256:
- return pg_be_scram_build_verifier(password);+ return pg_be_scram_build_secret(password);
case PASSWORD_TYPE_PLAINTEXT:
elog(ERROR, "cannot encrypt password with 'plaintext'");
diff --git a/src/common/scram-common.c b/src/common/scram-common.cindex dff9723e67..72bfa38a2e 100644--- a/src/common/scram-common.c+++ b/src/common/scram-common.c@@ -181,7 +181,7 @@ scram_ServerKey(const uint8 *salted_password, uint8 *result)
/*
- * Construct a verifier string for SCRAM, stored in pg_authid.rolpassword.+ * Construct a SCRAM secret, for storing in pg_authid.rolpassword.
*
* The password should already have been processed with SASLprep, if necessary!
*
@@ -189,7 +189,7 @@ scram_ServerKey(const uint8 *salted_password, uint8 *result)
* palloc'd or malloc'd, so caller is responsible for freeing it.
*/
char *
-scram_build_verifier(const char *salt, int saltlen, int iterations,+scram_build_secret(const char *salt, int saltlen, int iterations,
const char *password)
{
uint8 salted_password[SCRAM_KEY_LEN];
diff --git a/src/include/common/scram-common.h b/src/include/common/scram-common.hindex d52df67ec8..1c46dee58c 100644--- a/src/include/common/scram-common.h+++ b/src/include/common/scram-common.h@@ -33,14 +33,14 @@
#define SCRAM_RAW_NONCE_LEN 18
/*
- * Length of salt when generating new verifiers, in bytes. (It will be stored+ * Length of salt when generating new secrets, in bytes. (It will be stored
* and sent over the wire encoded in Base64.) 16 bytes is what the example in
* RFC 7677 uses.
*/
#define SCRAM_DEFAULT_SALT_LEN 16
/*
- * Default number of iterations when generating verifier. Should be at least+ * Default number of iterations when generating secret. Should be at least
* 4096 per RFC 7677.
*/
#define SCRAM_DEFAULT_ITERATIONS 4096
@@ -64,7 +64,7 @@ extern void scram_H(const uint8 *str, int len, uint8 *result);
extern void scram_ClientKey(const uint8 *salted_password, uint8 *result);
extern void scram_ServerKey(const uint8 *salted_password, uint8 *result);
-extern char *scram_build_verifier(const char *salt, int saltlen, int iterations,+extern char *scram_build_secret(const char *salt, int saltlen, int iterations,
const char *password);
#endif /* SCRAM_COMMON_H */
diff --git a/src/include/libpq/crypt.h b/src/include/libpq/crypt.hindex e6b50a7288..3564ef39d8 100644--- a/src/include/libpq/crypt.h+++ b/src/include/libpq/crypt.h@@ -16,7 +16,7 @@
#include "datatype/timestamp.h"
/*
- * Types of password hashes or verifiers.+ * Types of password hashes or secrets.
*
* Plaintext passwords can be passed in by the user, in a CREATE/ALTER USER
* command. They will be encrypted to MD5 or SCRAM-SHA-256 format, before
diff --git a/src/include/libpq/scram.h b/src/include/libpq/scram.hindex 87e2d56301..71fcb51c5a 100644--- a/src/include/libpq/scram.h+++ b/src/include/libpq/scram.h@@ -27,11 +27,11 @@ extern void *pg_be_scram_init(Port *port, const char *selected_mech, const char
extern int pg_be_scram_exchange(void *opaq, const char *input, int inputlen,
char **output, int *outputlen, char **logdetail);
-/* Routines to handle and check SCRAM-SHA-256 verifier */-extern char *pg_be_scram_build_verifier(const char *password);-extern bool parse_scram_verifier(const char *verifier, int *iterations, char **salt,+/* Routines to handle and check SCRAM-SHA-256 secret */+extern char *pg_be_scram_build_secret(const char *password);+extern bool parse_scram_secret(const char *secret, int *iterations, char **salt,
uint8 *stored_key, uint8 *server_key);
extern bool scram_verify_plain_password(const char *username,
- const char *password, const char *verifier);+ const char *password, const char *secret);
#endif /* PG_SCRAM_H */
diff --git a/src/interfaces/libpq/fe-auth-scram.c b/src/interfaces/libpq/fe-auth-scram.cindex 693739c544..741f566a72 100644--- a/src/interfaces/libpq/fe-auth-scram.c+++ b/src/interfaces/libpq/fe-auth-scram.c@@ -822,10 +822,10 @@ verify_server_signature(fe_scram_state *state)
}
/*
- * Build a new SCRAM verifier.+ * Build a new SCRAM secret.
*/
char *
-pg_fe_scram_build_verifier(const char *password)+pg_fe_scram_build_secret(const char *password)
{
char *prep_password;
pg_saslprep_rc rc;
@@ -851,7 +851,7 @@ pg_fe_scram_build_verifier(const char *password)
return NULL;
}
- result = scram_build_verifier(saltbuf, SCRAM_DEFAULT_SALT_LEN,+ result = scram_build_secret(saltbuf, SCRAM_DEFAULT_SALT_LEN,
SCRAM_DEFAULT_ITERATIONS, password);
if (prep_password)
diff --git a/src/interfaces/libpq/fe-auth.c b/src/interfaces/libpq/fe-auth.cindex 8ca7b39326..a690f3ba3a 100644--- a/src/interfaces/libpq/fe-auth.c+++ b/src/interfaces/libpq/fe-auth.c@@ -1251,7 +1251,7 @@ PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user,
*/
if (strcmp(algorithm, "scram-sha-256") == 0)
{
- crypt_pwd = pg_fe_scram_build_verifier(passwd);+ crypt_pwd = pg_fe_scram_build_secret(passwd);
}
else if (strcmp(algorithm, "md5") == 0)
{
diff --git a/src/interfaces/libpq/fe-auth.h b/src/interfaces/libpq/fe-auth.hindex 2f1af53fb0..3d3db41f8c 100644--- a/src/interfaces/libpq/fe-auth.h+++ b/src/interfaces/libpq/fe-auth.h@@ -31,6 +31,6 @@ extern void pg_fe_scram_free(void *opaq);
extern void pg_fe_scram_exchange(void *opaq, char *input, int inputlen,
char **output, int *outputlen,
bool *done, bool *success);
-extern char *pg_fe_scram_build_verifier(const char *password);+extern char *pg_fe_scram_build_secret(const char *password);
#endif /* FE_AUTH_H */
diff --git a/src/test/authentication/t/001_password.pl b/src/test/authentication/t/001_password.plindex aae6de8b34..5985130e3d 100644--- a/src/test/authentication/t/001_password.pl+++ b/src/test/authentication/t/001_password.pl@@ -82,7 +82,7 @@ sub test_role
test_role($node, 'md5_role', 'scram-sha-256', 2);
# For "md5" method, all users should be able to connect (SCRAM
-# authentication will be performed for the user with a scram verifier.)+# authentication will be performed for the user with a SCRAM secret.)
reset_pg_hba($node, 'md5');
test_role($node, 'scram_role', 'md5', 0);
test_role($node, 'md5_role', 'md5', 0);
diff --git a/src/test/regress/expected/password.out b/src/test/regress/expected/password.outindex f1ae34f15f..2b852aa324 100644--- a/src/test/regress/expected/password.out+++ b/src/test/regress/expected/password.out@@ -1,5 +1,5 @@
--
--- Tests for password verifiers+-- Tests for password types
--
-- Tests for GUC password_encryption
SET password_encryption = 'novalue'; -- error
@@ -18,7 +18,7 @@ CREATE ROLE regress_passwd3 PASSWORD 'role_pwd3';
CREATE ROLE regress_passwd4 PASSWORD NULL;
-- check list of created entries
--
--- The scram verifier will look something like:+-- The scram secret will look something like:
-- SCRAM-SHA-256$4096:E4HxLGtnRzsYwg==$6YtlR4t69SguDiwFvbVgVZtuz6gpJQQqUMZ7IQJK5yI=:ps75jrHeYU4lXCcXI4O8oIdJ3eO8o2jirjruw9phBTo=
--
-- Since the salt is random, the exact value stored will be different on every test
@@ -58,14 +58,14 @@ ALTER ROLE regress_passwd2 PASSWORD 'foo';
ALTER ROLE regress_passwd1 PASSWORD 'md5cd3578025fe2c3d7ed1b9a9b26238b70';
ALTER ROLE regress_passwd3 PASSWORD 'SCRAM-SHA-256$4096:VLK4RMaQLCvNtQ==$6YtlR4t69SguDiwFvbVgVZtuz6gpJQQqUMZ7IQJK5yI=:ps75jrHeYU4lXCcXI4O8oIdJ3eO8o2jirjruw9phBTo=';
SET password_encryption = 'scram-sha-256';
--- create SCRAM verifier+-- create SCRAM secret
ALTER ROLE regress_passwd4 PASSWORD 'foo';
-- already encrypted with MD5, use as it is
CREATE ROLE regress_passwd5 PASSWORD 'md5e73a4b11df52a6068f8b39f90be36023';
--- This looks like a valid SCRAM-SHA-256 verifier, but it is not+-- This looks like a valid SCRAM-SHA-256 secret, but it is not
-- so it should be hashed with SCRAM-SHA-256.
CREATE ROLE regress_passwd6 PASSWORD 'SCRAM-SHA-256$1234';
--- These may look like valid MD5 verifiers, but they are not, so they+-- These may look like valid MD5 secrets, but they are not, so they
-- should be hashed with SCRAM-SHA-256.
-- trailing garbage at the end
CREATE ROLE regress_passwd7 PASSWORD 'md5012345678901234567890123456789zz';
@@ -107,7 +107,7 @@ SELECT rolpassword FROM pg_authid WHERE rolname='regress_passwd_empty';
CREATE ROLE regress_passwd_sha_len0 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96Rqw=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZI=';
CREATE ROLE regress_passwd_sha_len1 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96RqwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZI=';
CREATE ROLE regress_passwd_sha_len2 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96Rqw=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=';
--- Check that the invalid verifiers were re-hashed. A re-hashed verifier+-- Check that the invalid secrets were re-hashed. A re-hashed secret
-- should not contain the original salt.
SELECT rolname, rolpassword not like '%A6xHKoH/494E941doaPOYg==%' as is_rolpassword_rehashed
FROM pg_authid
diff --git a/src/test/regress/sql/password.sql b/src/test/regress/sql/password.sqlindex fad88ba689..1e7e19eafa 100644--- a/src/test/regress/sql/password.sql+++ b/src/test/regress/sql/password.sql@@ -1,5 +1,5 @@
--
--- Tests for password verifiers+-- Tests for password types
--
-- Tests for GUC password_encryption
@@ -19,7 +19,7 @@ CREATE ROLE regress_passwd4 PASSWORD NULL;
-- check list of created entries
--
--- The scram verifier will look something like:+-- The scram secret will look something like:
-- SCRAM-SHA-256$4096:E4HxLGtnRzsYwg==$6YtlR4t69SguDiwFvbVgVZtuz6gpJQQqUMZ7IQJK5yI=:ps75jrHeYU4lXCcXI4O8oIdJ3eO8o2jirjruw9phBTo=
--
-- Since the salt is random, the exact value stored will be different on every test
@@ -49,15 +49,15 @@ CREATE ROLE regress_passwd4 PASSWORD NULL;
ALTER ROLE regress_passwd3 PASSWORD 'SCRAM-SHA-256$4096:VLK4RMaQLCvNtQ==$6YtlR4t69SguDiwFvbVgVZtuz6gpJQQqUMZ7IQJK5yI=:ps75jrHeYU4lXCcXI4O8oIdJ3eO8o2jirjruw9phBTo=';
SET password_encryption = 'scram-sha-256';
--- create SCRAM verifier+-- create SCRAM secret
ALTER ROLE regress_passwd4 PASSWORD 'foo';
-- already encrypted with MD5, use as it is
CREATE ROLE regress_passwd5 PASSWORD 'md5e73a4b11df52a6068f8b39f90be36023';
--- This looks like a valid SCRAM-SHA-256 verifier, but it is not+-- This looks like a valid SCRAM-SHA-256 secret, but it is not
-- so it should be hashed with SCRAM-SHA-256.
CREATE ROLE regress_passwd6 PASSWORD 'SCRAM-SHA-256$1234';
--- These may look like valid MD5 verifiers, but they are not, so they+-- These may look like valid MD5 secrets, but they are not, so they
-- should be hashed with SCRAM-SHA-256.
-- trailing garbage at the end
CREATE ROLE regress_passwd7 PASSWORD 'md5012345678901234567890123456789zz';
@@ -83,7 +83,7 @@ CREATE ROLE regress_passwd_sha_len0 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941
CREATE ROLE regress_passwd_sha_len1 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96RqwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZI=';
CREATE ROLE regress_passwd_sha_len2 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96Rqw=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=';
--- Check that the invalid verifiers were re-hashed. A re-hashed verifier+-- Check that the invalid secrets were re-hashed. A re-hashed secret
-- should not contain the original salt.
SELECT rolname, rolpassword not like '%A6xHKoH/494E941doaPOYg==%' as is_rolpassword_rehashed
FROM pg_authid
--
2.23.0
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-hackers@postgresql.org
Cc: peter.eisentraut@2ndquadrant.com, hlinnaka@iki.fi
Subject: Re: use of the term "verifier" with SCRAM
In-Reply-To: <73ba767c-f7dc-ce9e-3810-0daa184918a0@2ndquadrant.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox