Fix scram with pg version num >= 140 000 (#383)

This commit is contained in:
kirill reshke 2021-12-09 12:26:27 +05:00 committed by GitHub
parent ee9b0e23e2
commit cb508c3d78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 102 additions and 57 deletions

View File

@ -131,7 +131,33 @@ database "postgres" {
quantiles "0.99,0.95,0.5"
client_max 107
}
user "user_scram" {
authentication "scram-sha-256"
password "12"
storage "postgres_server"
pool "transaction"
pool_size 1
pool_timeout 0
pool_ttl 60
pool_discard no
pool_cancel yes
pool_rollback yes
client_fwd_error yes
application_name_add_host yes
reserve_session_server_connection no
server_lifetime 3600
log_debug no
quantiles "0.99,0.95,0.5"
client_max 107
}
user "userstmt" {
authentication "none"

View File

@ -300,7 +300,7 @@ static int calculate_client_proof(od_scram_state_t *scram_state,
if (scram_state->salted_password == NULL)
goto error;
od_scram_ctx_t ctx;
od_scram_ctx_t *ctx = od_scram_HMAC_create();
scram_SaltedPassword(prepared_password, salt, strlen(salt), iterations,
scram_state->salted_password);
@ -310,23 +310,25 @@ static int calculate_client_proof(od_scram_state_t *scram_state,
uint8_t stored_key[SCRAM_KEY_LEN];
scram_H(client_key, SCRAM_KEY_LEN, stored_key);
od_scram_HMAC_init(&ctx, stored_key, SCRAM_KEY_LEN);
od_scram_HMAC_init(ctx, stored_key, SCRAM_KEY_LEN);
od_scram_HMAC_update(&ctx, scram_state->client_first_message,
od_scram_HMAC_update(ctx, scram_state->client_first_message,
strlen(scram_state->client_first_message));
od_scram_HMAC_update(&ctx, ",", 1);
od_scram_HMAC_update(&ctx, scram_state->server_first_message,
od_scram_HMAC_update(ctx, ",", 1);
od_scram_HMAC_update(ctx, scram_state->server_first_message,
strlen(scram_state->server_first_message));
od_scram_HMAC_update(&ctx, ",", 1);
od_scram_HMAC_update(&ctx, client_final_message,
od_scram_HMAC_update(ctx, ",", 1);
od_scram_HMAC_update(ctx, client_final_message,
strlen(client_final_message));
uint8_t client_signature[SCRAM_KEY_LEN];
od_scram_HMAC_final(client_signature, &ctx);
od_scram_HMAC_final(client_signature, ctx);
for (int i = 0; i < SCRAM_KEY_LEN; i++)
client_proof[i] = client_key[i] ^ client_signature[i];
od_scram_HMAC_free(ctx);
free(prepared_password);
return 0;
@ -338,20 +340,21 @@ error:
static char *calculate_server_signature(od_scram_state_t *scram_state)
{
od_scram_ctx_t ctx;
od_scram_ctx_t *ctx = od_scram_HMAC_create();
od_scram_HMAC_init(&ctx, scram_state->server_key, SCRAM_KEY_LEN);
od_scram_HMAC_update(&ctx, scram_state->client_first_message,
od_scram_HMAC_init(ctx, scram_state->server_key, SCRAM_KEY_LEN);
od_scram_HMAC_update(ctx, scram_state->client_first_message,
strlen(scram_state->client_first_message));
od_scram_HMAC_update(&ctx, ",", 1);
od_scram_HMAC_update(&ctx, scram_state->server_first_message,
od_scram_HMAC_update(ctx, ",", 1);
od_scram_HMAC_update(ctx, scram_state->server_first_message,
strlen(scram_state->server_first_message));
od_scram_HMAC_update(&ctx, ",", 1);
od_scram_HMAC_update(&ctx, scram_state->client_final_message,
od_scram_HMAC_update(ctx, ",", 1);
od_scram_HMAC_update(ctx, scram_state->client_final_message,
strlen(scram_state->client_final_message));
uint8_t server_signature[SCRAM_KEY_LEN];
od_scram_HMAC_final(server_signature, &ctx);
od_scram_HMAC_final(server_signature, ctx);
od_scram_HMAC_free(ctx);
int base64_signature_dst_len = pg_b64_enc_len(SCRAM_KEY_LEN) + 1;
char *base64_signature = malloc(base64_signature_dst_len);
@ -464,39 +467,42 @@ error:
return -1;
}
int od_scram_verify_server_signature(od_scram_state_t *scram_state,
char *auth_data, size_t auth_data_size)
od_retcode_t od_scram_verify_server_signature(od_scram_state_t *scram_state,
char *auth_data,
size_t auth_data_size)
{
char server_signature[SHA256_DIGEST_LENGTH];
int rc = read_server_final_message(auth_data, auth_data_size,
server_signature);
if (rc == -1)
return -1;
od_retcode_t rc = read_server_final_message(auth_data, auth_data_size,
server_signature);
if (rc == NOT_OK_RESPONSE)
return NOT_OK_RESPONSE;
od_scram_ctx_t ctx;
od_scram_ctx_t *ctx = od_scram_HMAC_create();
uint8_t server_key[SCRAM_KEY_LEN];
scram_ServerKey(scram_state->salted_password, server_key);
od_scram_HMAC_init(&ctx, server_key, SCRAM_KEY_LEN);
od_scram_HMAC_init(ctx, server_key, SCRAM_KEY_LEN);
od_scram_HMAC_update(&ctx, scram_state->client_first_message,
od_scram_HMAC_update(ctx, scram_state->client_first_message,
strlen(scram_state->client_first_message));
od_scram_HMAC_update(&ctx, ",", 1);
od_scram_HMAC_update(&ctx, scram_state->server_first_message,
od_scram_HMAC_update(ctx, ",", 1);
od_scram_HMAC_update(ctx, scram_state->server_first_message,
strlen(scram_state->server_first_message));
od_scram_HMAC_update(&ctx, ",", 1);
od_scram_HMAC_update(&ctx, scram_state->client_final_message,
od_scram_HMAC_update(ctx, ",", 1);
od_scram_HMAC_update(ctx, scram_state->client_final_message,
strlen(scram_state->client_final_message));
uint8_t expected_server_signature[SHA256_DIGEST_LENGTH];
od_scram_HMAC_final(expected_server_signature, &ctx);
od_scram_HMAC_final(expected_server_signature, ctx);
od_scram_HMAC_free(ctx);
if (memcmp(expected_server_signature, server_signature,
SHA256_DIGEST_LENGTH) != 0)
return -1;
return NOT_OK_RESPONSE;
return 0;
return OK_RESPONSE;
}
int od_scram_read_client_first_message(od_scram_state_t *scram_state,
@ -710,56 +716,59 @@ error:
return NULL;
}
int od_scram_verify_final_nonce(od_scram_state_t *scram_state,
char *final_nonce, size_t final_nonce_size)
od_retcode_t od_scram_verify_final_nonce(od_scram_state_t *scram_state,
char *final_nonce,
size_t final_nonce_size)
{
size_t client_nonce_len = strlen(scram_state->client_nonce);
size_t server_nonce_len = strlen(scram_state->server_nonce);
if (final_nonce_size != client_nonce_len + server_nonce_len)
return -1;
return NOT_OK_RESPONSE;
if (memcmp(final_nonce, scram_state->client_nonce, client_nonce_len) !=
0)
return -1;
return NOT_OK_RESPONSE;
if (memcmp(final_nonce + client_nonce_len, scram_state->server_nonce,
server_nonce_len) != 0)
return -1;
return NOT_OK_RESPONSE;
return 0;
return OK_RESPONSE;
}
int od_scram_verify_client_proof(od_scram_state_t *scram_state,
char *client_proof)
od_retcode_t od_scram_verify_client_proof(od_scram_state_t *scram_state,
char *client_proof)
{
uint8_t client_signature[SCRAM_KEY_LEN];
uint8_t client_key[SCRAM_KEY_LEN];
uint8_t client_stored_key[SCRAM_KEY_LEN];
od_scram_ctx_t ctx;
od_scram_ctx_t *ctx = od_scram_HMAC_create();
od_scram_HMAC_init(&ctx, scram_state->stored_key, SCRAM_KEY_LEN);
od_scram_HMAC_update(&ctx, scram_state->client_first_message,
od_scram_HMAC_init(ctx, scram_state->stored_key, SCRAM_KEY_LEN);
od_scram_HMAC_update(ctx, scram_state->client_first_message,
strlen(scram_state->client_first_message));
od_scram_HMAC_update(&ctx, ",", 1);
od_scram_HMAC_update(&ctx, scram_state->server_first_message,
od_scram_HMAC_update(ctx, ",", 1);
od_scram_HMAC_update(ctx, scram_state->server_first_message,
strlen(scram_state->server_first_message));
od_scram_HMAC_update(&ctx, ",", 1);
od_scram_HMAC_update(&ctx, scram_state->client_final_message,
od_scram_HMAC_update(ctx, ",", 1);
od_scram_HMAC_update(ctx, scram_state->client_final_message,
strlen(scram_state->client_final_message));
od_scram_HMAC_final(client_signature, &ctx);
od_scram_HMAC_final(client_signature, ctx);
for (int i = 0; i < SCRAM_KEY_LEN; i++)
client_key[i] = client_proof[i] ^ client_signature[i];
scram_H(client_key, SCRAM_KEY_LEN, client_stored_key);
od_scram_HMAC_free(ctx);
if (memcmp(client_stored_key, scram_state->stored_key, SCRAM_KEY_LEN) !=
0)
return -1;
return NOT_OK_RESPONSE;
return 0;
return OK_RESPONSE;
}
machine_msg_t *

View File

@ -23,24 +23,34 @@
typedef scram_HMAC_ctx od_scram_ctx_t;
#define od_scram_HMAC_init scram_HMAC_init
#define od_scram_HMAC_create() malloc(sizeof(od_scram_ctx_t))
#define od_scram_HMAC_update scram_HMAC_update
#define od_scram_HMAC_final scram_HMAC_final
#define od_scram_HMAC_free(ctx) free(ctx)
#else
struct pg_hmac_ctx {
HMAC_CTX *hmacctx;
pg_cryptohash_type type;
#ifndef FRONTEND
ResourceOwner resowner;
#endif
struct pg_hmac_ctx {
pg_cryptohash_ctx *hash;
pg_cryptohash_type type;
int block_size;
int digest_size;
/*
* Use the largest block size among supported options. This wastes some
* memory but simplifies the allocation logic.
*/
uint8 k_ipad[PG_SHA512_BLOCK_LENGTH];
uint8 k_opad[PG_SHA512_BLOCK_LENGTH];
};
typedef struct pg_hmac_ctx od_scram_ctx_t;
#define od_scram_HMAC_init pg_hmac_init
#define od_scram_HMAC_create() pg_hmac_create(PG_SHA256)
#define od_scram_HMAC_update pg_hmac_update
#define od_scram_HMAC_final(dest, ctx) pg_hmac_final(ctx, dest, sizeof(dest))
#define od_scram_HMAC_free pg_hmac_free
#endif