aboutsummaryrefslogtreecommitdiff
path: root/src/common/scram-common.c
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2017-04-28 15:04:02 +0300
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2017-04-28 15:22:38 +0300
commitd981074c24d2f1e4f44bc6d80e967e523ce64f50 (patch)
treeaca39492e91899c6fca0e7a23e72b0894c438eed /src/common/scram-common.c
parentb9a3ef55b253d885081c2d0e9dc45802cab71c7b (diff)
downloadpostgresql-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/common/scram-common.c')
-rw-r--r--src/common/scram-common.c51
1 files changed, 33 insertions, 18 deletions
diff --git a/src/common/scram-common.c b/src/common/scram-common.c
index df9f0eaa90d..a8ea44944c4 100644
--- a/src/common/scram-common.c
+++ b/src/common/scram-common.c
@@ -98,14 +98,16 @@ scram_HMAC_final(uint8 *result, scram_HMAC_ctx *ctx)
}
/*
- * Iterate hash calculation of HMAC entry using given salt.
- * scram_Hi() is essentially PBKDF2 (see RFC2898) with HMAC() as the
- * pseudorandom function.
+ * Calculate SaltedPassword.
+ *
+ * The password should already be normalized by SASLprep.
*/
-static void
-scram_Hi(const char *str, const char *salt, int saltlen, int iterations, uint8 *result)
+void
+scram_SaltedPassword(const char *password,
+ const char *salt, int saltlen, int iterations,
+ uint8 *result)
{
- int str_len = strlen(str);
+ int password_len = strlen(password);
uint32 one = htonl(1);
int i,
j;
@@ -113,8 +115,14 @@ scram_Hi(const char *str, const char *salt, int saltlen, int iterations, uint8 *
uint8 Ui_prev[SCRAM_KEY_LEN];
scram_HMAC_ctx hmac_ctx;
+ /*
+ * Iterate hash calculation of HMAC entry using given salt. This is
+ * essentially PBKDF2 (see RFC2898) with HMAC() as the pseudorandom
+ * function.
+ */
+
/* First iteration */
- scram_HMAC_init(&hmac_ctx, (uint8 *) str, str_len);
+ scram_HMAC_init(&hmac_ctx, (uint8 *) password, password_len);
scram_HMAC_update(&hmac_ctx, salt, saltlen);
scram_HMAC_update(&hmac_ctx, (char *) &one, sizeof(uint32));
scram_HMAC_final(Ui_prev, &hmac_ctx);
@@ -123,7 +131,7 @@ scram_Hi(const char *str, const char *salt, int saltlen, int iterations, uint8 *
/* Subsequent iterations */
for (i = 2; i <= iterations; i++)
{
- scram_HMAC_init(&hmac_ctx, (uint8 *) str, str_len);
+ scram_HMAC_init(&hmac_ctx, (uint8 *) password, password_len);
scram_HMAC_update(&hmac_ctx, (const char *) Ui_prev, SCRAM_KEY_LEN);
scram_HMAC_final(Ui, &hmac_ctx);
for (j = 0; j < SCRAM_KEY_LEN; j++)
@@ -148,20 +156,27 @@ scram_H(const uint8 *input, int len, uint8 *result)
}
/*
- * Calculate ClientKey or ServerKey.
- *
- * The password should already be normalized by SASLprep.
+ * Calculate ClientKey.
*/
void
-scram_ClientOrServerKey(const char *password,
- const char *salt, int saltlen, int iterations,
- const char *keystr, uint8 *result)
+scram_ClientKey(const uint8 *salted_password, uint8 *result)
+{
+ scram_HMAC_ctx ctx;
+
+ scram_HMAC_init(&ctx, salted_password, SCRAM_KEY_LEN);
+ scram_HMAC_update(&ctx, "Client Key", strlen("Client Key"));
+ scram_HMAC_final(result, &ctx);
+}
+
+/*
+ * Calculate ServerKey.
+ */
+void
+scram_ServerKey(const uint8 *salted_password, uint8 *result)
{
- uint8 keybuf[SCRAM_KEY_LEN];
scram_HMAC_ctx ctx;
- scram_Hi(password, salt, saltlen, iterations, keybuf);
- scram_HMAC_init(&ctx, keybuf, SCRAM_KEY_LEN);
- scram_HMAC_update(&ctx, keystr, strlen(keystr));
+ scram_HMAC_init(&ctx, salted_password, SCRAM_KEY_LEN);
+ scram_HMAC_update(&ctx, "Server Key", strlen("Server Key"));
scram_HMAC_final(result, &ctx);
}