use of the term "verifier" with SCRAM
I'm confused by how the code uses the term "verifier" in relation to SCRAM.
ISTM that the code uses the term as meaning whatever is or would be
stored in pg_auth.rolpassword.
I don't see this usage supported in the RFCs. In RFC 5802,
verifier = "v=" base64
;; base-64 encoded ServerSignature.
where
ServerSignature := HMAC(ServerKey, AuthMessage)
ServerKey := HMAC(SaltedPassword, "Server Key")
AuthMessage := client-first-message-bare + "," +
server-first-message + "," +
client-final-message-without-proof
whereas what is stored in rolpassword is
SCRAM-SHA-256$<iterations>:<salt>$<storedkey>:<serverkey>
where
StoredKey := H(ClientKey)
ClientKey := HMAC(SaltedPassword, "Client Key")
So while these are all related, I don't think it's accurate to call what
is in rolpassword a SCRAM "verifier".
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.
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
On 14/08/2019 08:59, Peter Eisentraut wrote:
I'm confused by how the code uses the term "verifier" in relation to SCRAM.
ISTM that the code uses the term as meaning whatever is or would be
stored in pg_auth.rolpassword.I don't see this usage supported in the RFCs. In RFC 5802,
verifier = "v=" base64
;; base-64 encoded ServerSignature.where
ServerSignature := HMAC(ServerKey, AuthMessage)
ServerKey := HMAC(SaltedPassword, "Server Key")
AuthMessage := client-first-message-bare + "," +
server-first-message + "," +
client-final-message-without-proofwhereas what is stored in rolpassword is
SCRAM-SHA-256$<iterations>:<salt>$<storedkey>:<serverkey>
where
StoredKey := H(ClientKey)
ClientKey := HMAC(SaltedPassword, "Client Key")So while these are all related, I don't think it's accurate to call what
is in rolpassword a SCRAM "verifier".
Huh, you're right.
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.
RFC 5802 uses the term "Authentication information". See section "2.1
Terminology":
o Authentication information: Information used to verify an identity
claimed by a SCRAM client. The authentication information for a
SCRAM identity consists of salt, iteration count, "StoredKey" and
"ServerKey" (as defined in the algorithm overview) for each
supported cryptographic hash function.
But I agree that "secret", as used in RFC5803 is better.
- Heikki
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
Attachments:
0001-Fix-use-of-term-verifier.patchtext/plain; charset=UTF-8; name=0001-Fix-use-of-term-verifier.patch; x-mac-creator=0; x-mac-type=0Download
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.c
index 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.c
index 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.c
index 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.c
index 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.h
index 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.h
index 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.h
index 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.c
index 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.c
index 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.h
index 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.pl
index 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.out
index 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.sql
index 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
On Thu, Oct 10, 2019 at 09:08:37AM +0200, Peter Eisentraut wrote:
Here is my proposed patch to adjust this.
Looks fine to me reading through. I think that you are right to not
change the descriptions in build_server_final_message(), as that's
described similarly in RFC 5802. By renaming scram_build_verifier()
to scram_build_secret() you are going to break one of my in-house
extensions. I am using it to register for a user SCRAM veri^D^D^D^D
secrets with custom iteration and salt length :)
--
Michael
On 2019-10-10 10:03, Michael Paquier wrote:
On Thu, Oct 10, 2019 at 09:08:37AM +0200, Peter Eisentraut wrote:
Here is my proposed patch to adjust this.
Looks fine to me reading through. I think that you are right to not
change the descriptions in build_server_final_message(), as that's
described similarly in RFC 5802.
committed
By renaming scram_build_verifier()
to scram_build_secret() you are going to break one of my in-house
extensions. I am using it to register for a user SCRAM veri^D^D^D^D
secrets with custom iteration and salt length :)
OK, that should be easy to work around with an #ifdef or two.
--
Peter Eisentraut http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services