diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2017-04-28 15:04:02 +0300 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2017-04-28 15:22:38 +0300 |
commit | d981074c24d2f1e4f44bc6d80e967e523ce64f50 (patch) | |
tree | aca39492e91899c6fca0e7a23e72b0894c438eed /src/backend | |
parent | b9a3ef55b253d885081c2d0e9dc45802cab71c7b (diff) | |
download | postgresql-d981074c24d2f1e4f44bc6d80e967e523ce64f50.tar.gz postgresql-d981074c24d2f1e4f44bc6d80e967e523ce64f50.zip |
Misc SCRAM code cleanups.
* Move computation of SaltedPassword to a separate function from
scram_ClientOrServerKey(). This saves a lot of cycles in libpq, by
computing SaltedPassword only once per authentication. (Computing
SaltedPassword is expensive by design.)
* Split scram_ClientOrServerKey() into two functions. Improves
readability, by making the calling code less verbose.
* Rename "server proof" to "server signature", to better match the
nomenclature used in RFC 5802.
* Rename SCRAM_SALT_LEN to SCRAM_DEFAULT_SALT_LEN, to make it more clear
that the salt can be of any length, and the constant only specifies how
long a salt we use when we generate a new verifier. Also rename
SCRAM_ITERATIONS_DEFAULT to SCRAM_DEFAULT_ITERATIONS, for consistency.
These things caught my eye while working on other upcoming changes.
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/libpq/auth-scram.c | 36 |
1 files changed, 19 insertions, 17 deletions
diff --git a/src/backend/libpq/auth-scram.c b/src/backend/libpq/auth-scram.c index 16bea446e37..5c85af943cd 100644 --- a/src/backend/libpq/auth-scram.c +++ b/src/backend/libpq/auth-scram.c @@ -396,7 +396,8 @@ scram_build_verifier(const char *username, const char *password, { char *prep_password = NULL; pg_saslprep_rc rc; - char saltbuf[SCRAM_SALT_LEN]; + char saltbuf[SCRAM_DEFAULT_SALT_LEN]; + uint8 salted_password[SCRAM_KEY_LEN]; uint8 keybuf[SCRAM_KEY_LEN]; char *encoded_salt; char *encoded_storedkey; @@ -414,10 +415,10 @@ scram_build_verifier(const char *username, const char *password, password = (const char *) prep_password; if (iterations <= 0) - iterations = SCRAM_ITERATIONS_DEFAULT; + iterations = SCRAM_DEFAULT_ITERATIONS; /* Generate salt, and encode it in base64 */ - if (!pg_backend_random(saltbuf, SCRAM_SALT_LEN)) + if (!pg_backend_random(saltbuf, SCRAM_DEFAULT_SALT_LEN)) { ereport(LOG, (errcode(ERRCODE_INTERNAL_ERROR), @@ -425,13 +426,14 @@ scram_build_verifier(const char *username, const char *password, return NULL; } - encoded_salt = palloc(pg_b64_enc_len(SCRAM_SALT_LEN) + 1); - encoded_len = pg_b64_encode(saltbuf, SCRAM_SALT_LEN, encoded_salt); + encoded_salt = palloc(pg_b64_enc_len(SCRAM_DEFAULT_SALT_LEN) + 1); + encoded_len = pg_b64_encode(saltbuf, SCRAM_DEFAULT_SALT_LEN, encoded_salt); encoded_salt[encoded_len] = '\0'; /* Calculate StoredKey, and encode it in base64 */ - scram_ClientOrServerKey(password, saltbuf, SCRAM_SALT_LEN, - iterations, SCRAM_CLIENT_KEY_NAME, keybuf); + scram_SaltedPassword(password, saltbuf, SCRAM_DEFAULT_SALT_LEN, + iterations, salted_password); + scram_ClientKey(salted_password, keybuf); scram_H(keybuf, SCRAM_KEY_LEN, keybuf); /* StoredKey */ encoded_storedkey = palloc(pg_b64_enc_len(SCRAM_KEY_LEN) + 1); @@ -440,8 +442,7 @@ scram_build_verifier(const char *username, const char *password, encoded_storedkey[encoded_len] = '\0'; /* And same for ServerKey */ - scram_ClientOrServerKey(password, saltbuf, SCRAM_SALT_LEN, iterations, - SCRAM_SERVER_KEY_NAME, keybuf); + scram_ServerKey(salted_password, keybuf); encoded_serverkey = palloc(pg_b64_enc_len(SCRAM_KEY_LEN) + 1); encoded_len = pg_b64_encode((const char *) keybuf, SCRAM_KEY_LEN, @@ -473,6 +474,7 @@ scram_verify_plain_password(const char *username, const char *password, 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]; @@ -502,9 +504,9 @@ scram_verify_plain_password(const char *username, const char *password, if (rc == SASLPREP_SUCCESS) password = prep_password; - /* Compute Server key based on the user-supplied plaintext password */ - scram_ClientOrServerKey(password, salt, saltlen, iterations, - SCRAM_SERVER_KEY_NAME, computed_key); + /* 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); @@ -630,12 +632,12 @@ mock_scram_verifier(const char *username, int *iterations, char **salt, /* Generate deterministic salt */ raw_salt = scram_MockSalt(username); - encoded_salt = (char *) palloc(pg_b64_enc_len(SCRAM_SALT_LEN) + 1); - encoded_len = pg_b64_encode(raw_salt, SCRAM_SALT_LEN, encoded_salt); + encoded_salt = (char *) palloc(pg_b64_enc_len(SCRAM_DEFAULT_SALT_LEN) + 1); + encoded_len = pg_b64_encode(raw_salt, SCRAM_DEFAULT_SALT_LEN, encoded_salt); encoded_salt[encoded_len] = '\0'; *salt = encoded_salt; - *iterations = SCRAM_ITERATIONS_DEFAULT; + *iterations = SCRAM_DEFAULT_ITERATIONS; /* StoredKey and ServerKey are not used in a doomed authentication */ memset(stored_key, 0, SCRAM_KEY_LEN); @@ -1179,7 +1181,7 @@ build_server_final_message(scram_state *state) /* * Determinisitcally generate salt for mock authentication, using a SHA256 * hash based on the username and a cluster-level secret key. Returns a - * pointer to a static buffer of size SCRAM_SALT_LEN. + * pointer to a static buffer of size SCRAM_DEFAULT_SALT_LEN. */ static char * scram_MockSalt(const char *username) @@ -1194,7 +1196,7 @@ scram_MockSalt(const char *username) * not larger the SHA256 digest length. If the salt is smaller, the caller * will just ignore the extra data)) */ - StaticAssertStmt(PG_SHA256_DIGEST_LENGTH >= SCRAM_SALT_LEN, + StaticAssertStmt(PG_SHA256_DIGEST_LENGTH >= SCRAM_DEFAULT_SALT_LEN, "salt length greater than SHA256 digest length"); pg_sha256_init(&ctx); |