pg_cryptohash_v4.patch
application/octet-stream
Filename: pg_cryptohash_v4.patch
Type: application/octet-stream
Part: 0
Patch
Format: unified
Series: patch v4
| File | + | − |
|---|---|---|
| contrib/pgcrypto/internal.c | 2 | 2 |
| contrib/pgcrypto/internal-sha2.c | 1 | 1 |
| src/backend/libpq/auth-scram.c | 4 | 3 |
| src/backend/replication/backup_manifest.c | 2 | 1 |
| src/backend/utils/adt/cryptohashfuncs.c | 2 | 1 |
| src/bin/pg_verifybackup/parse_manifest.c | 2 | 1 |
| src/common/checksum_helper.c | 8 | 4 |
| src/common/cryptohash.c | 15 | 3 |
| src/common/cryptohash_openssl.c | 32 | 1 |
| src/common/md5_common.c | 3 | 2 |
| src/common/scram-common.c | 12 | 9 |
| src/include/common/cryptohash.h | 1 | 1 |
| src/include/common/scram-common.h | 1 | 1 |
| src/interfaces/libpq/fe-auth-scram.c | 2 | 2 |
diff --git a/contrib/pgcrypto/internal-sha2.c b/contrib/pgcrypto/internal-sha2.c
index 0fe53e15af..c0d9eea731 100644
--- a/contrib/pgcrypto/internal-sha2.c
+++ b/contrib/pgcrypto/internal-sha2.c
@@ -118,7 +118,7 @@ int_sha2_finish(PX_MD *h, uint8 *dst)
{
pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr;
- if (pg_cryptohash_final(ctx, dst) < 0)
+ if (pg_cryptohash_final(ctx, dst, PG_SHA224_DIGEST_LENGTH) < 0)
elog(ERROR, "could not finalize %s context", "SHA2");
}
diff --git a/contrib/pgcrypto/internal.c b/contrib/pgcrypto/internal.c
index ef6ce2fb1e..955501b4d4 100644
--- a/contrib/pgcrypto/internal.c
+++ b/contrib/pgcrypto/internal.c
@@ -106,7 +106,7 @@ int_md5_finish(PX_MD *h, uint8 *dst)
{
pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr;
- if (pg_cryptohash_final(ctx, dst) < 0)
+ if (pg_cryptohash_final(ctx, dst, MD5_DIGEST_LENGTH) < 0)
elog(ERROR, "could not finalize %s context", "MD5");
}
@@ -156,7 +156,7 @@ int_sha1_finish(PX_MD *h, uint8 *dst)
{
pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr;
- if (pg_cryptohash_final(ctx, dst) < 0)
+ if (pg_cryptohash_final(ctx, dst, SHA1_DIGEST_LENGTH) < 0)
elog(ERROR, "could not finalize %s context", "SHA1");
}
diff --git a/src/backend/libpq/auth-scram.c b/src/backend/libpq/auth-scram.c
index 8d857f39df..284b03c50e 100644
--- a/src/backend/libpq/auth-scram.c
+++ b/src/backend/libpq/auth-scram.c
@@ -1120,7 +1120,7 @@ verify_client_proof(scram_state *state)
scram_HMAC_update(&ctx,
state->client_final_message_without_proof,
strlen(state->client_final_message_without_proof)) < 0 ||
- scram_HMAC_final(ClientSignature, &ctx) < 0)
+ scram_HMAC_final(&ctx, ClientSignature) < 0)
{
elog(ERROR, "could not calculate client signature");
}
@@ -1374,7 +1374,7 @@ build_server_final_message(scram_state *state)
scram_HMAC_update(&ctx,
state->client_final_message_without_proof,
strlen(state->client_final_message_without_proof)) < 0 ||
- scram_HMAC_final(ServerSignature, &ctx) < 0)
+ scram_HMAC_final(&ctx, ServerSignature) < 0)
{
elog(ERROR, "could not calculate server signature");
}
@@ -1429,7 +1429,8 @@ scram_mock_salt(const char *username)
if (pg_cryptohash_init(ctx) < 0 ||
pg_cryptohash_update(ctx, (uint8 *) username, strlen(username)) < 0 ||
pg_cryptohash_update(ctx, (uint8 *) mock_auth_nonce, MOCK_AUTH_NONCE_LEN) < 0 ||
- pg_cryptohash_final(ctx, sha_digest) < 0)
+ pg_cryptohash_final(ctx, sha_digest,
+ sizeof(sha_digest) - 1) < 0)
{
pg_cryptohash_free(ctx);
return NULL;
diff --git a/src/backend/replication/backup_manifest.c b/src/backend/replication/backup_manifest.c
index 0cefd181b5..5516ed4948 100644
--- a/src/backend/replication/backup_manifest.c
+++ b/src/backend/replication/backup_manifest.c
@@ -330,7 +330,8 @@ SendBackupManifest(backup_manifest_info *manifest)
* twice.
*/
manifest->still_checksumming = false;
- if (pg_cryptohash_final(manifest->manifest_ctx, checksumbuf) < 0)
+ if (pg_cryptohash_final(manifest->manifest_ctx, checksumbuf,
+ sizeof(checksumbuf) - 1) < 0)
elog(ERROR, "failed to finalize checksum of backup manifest");
AppendStringToManifest(manifest, "\"Manifest-Checksum\": \"");
dstlen = pg_hex_enc_len(PG_SHA256_DIGEST_LENGTH);
diff --git a/src/backend/utils/adt/cryptohashfuncs.c b/src/backend/utils/adt/cryptohashfuncs.c
index 152adcbfb4..6a0f0258e6 100644
--- a/src/backend/utils/adt/cryptohashfuncs.c
+++ b/src/backend/utils/adt/cryptohashfuncs.c
@@ -114,7 +114,8 @@ cryptohash_internal(pg_cryptohash_type type, bytea *input)
elog(ERROR, "could not initialize %s context", typestr);
if (pg_cryptohash_update(ctx, data, len) < 0)
elog(ERROR, "could not update %s context", typestr);
- if (pg_cryptohash_final(ctx, (unsigned char *) VARDATA(result)) < 0)
+ if (pg_cryptohash_final(ctx, (unsigned char *) VARDATA(result),
+ digest_len) < 0)
elog(ERROR, "could not finalize %s context", typestr);
pg_cryptohash_free(ctx);
diff --git a/src/bin/pg_verifybackup/parse_manifest.c b/src/bin/pg_verifybackup/parse_manifest.c
index db2fa90cfe..28c1bfbe5c 100644
--- a/src/bin/pg_verifybackup/parse_manifest.c
+++ b/src/bin/pg_verifybackup/parse_manifest.c
@@ -659,7 +659,8 @@ verify_manifest_checksum(JsonManifestParseState *parse, char *buffer,
context->error_cb(context, "could not initialize checksum of manifest");
if (pg_cryptohash_update(manifest_ctx, (uint8 *) buffer, penultimate_newline + 1) < 0)
context->error_cb(context, "could not update checksum of manifest");
- if (pg_cryptohash_final(manifest_ctx, manifest_checksum_actual) < 0)
+ if (pg_cryptohash_final(manifest_ctx, manifest_checksum_actual,
+ PG_SHA256_DIGEST_LENGTH) < 0)
context->error_cb(context, "could not finalize checksum of manifest");
/* Now verify it. */
diff --git a/src/common/checksum_helper.c b/src/common/checksum_helper.c
index a895e2e285..54b684d5e8 100644
--- a/src/common/checksum_helper.c
+++ b/src/common/checksum_helper.c
@@ -198,25 +198,29 @@ pg_checksum_final(pg_checksum_context *context, uint8 *output)
memcpy(output, &context->raw_context.c_crc32c, retval);
break;
case CHECKSUM_TYPE_SHA224:
- if (pg_cryptohash_final(context->raw_context.c_sha2, output) < 0)
+ if (pg_cryptohash_final(context->raw_context.c_sha2,
+ output, PG_SHA224_DIGEST_LENGTH) < 0)
return -1;
pg_cryptohash_free(context->raw_context.c_sha2);
retval = PG_SHA224_DIGEST_LENGTH;
break;
case CHECKSUM_TYPE_SHA256:
- if (pg_cryptohash_final(context->raw_context.c_sha2, output) < 0)
+ if (pg_cryptohash_final(context->raw_context.c_sha2,
+ output, PG_SHA256_DIGEST_LENGTH) < 0)
return -1;
pg_cryptohash_free(context->raw_context.c_sha2);
retval = PG_SHA256_DIGEST_LENGTH;
break;
case CHECKSUM_TYPE_SHA384:
- if (pg_cryptohash_final(context->raw_context.c_sha2, output) < 0)
+ if (pg_cryptohash_final(context->raw_context.c_sha2,
+ output, PG_SHA384_DIGEST_LENGTH) < 0)
return -1;
pg_cryptohash_free(context->raw_context.c_sha2);
retval = PG_SHA384_DIGEST_LENGTH;
break;
case CHECKSUM_TYPE_SHA512:
- if (pg_cryptohash_final(context->raw_context.c_sha2, output) < 0)
+ if (pg_cryptohash_final(context->raw_context.c_sha2,
+ output, PG_SHA512_DIGEST_LENGTH) < 0)
return -1;
pg_cryptohash_free(context->raw_context.c_sha2);
retval = PG_SHA512_DIGEST_LENGTH;
diff --git a/src/common/cryptohash.c b/src/common/cryptohash.c
index 5b2c050d79..9ab36003c9 100644
--- a/src/common/cryptohash.c
+++ b/src/common/cryptohash.c
@@ -161,11 +161,11 @@ pg_cryptohash_update(pg_cryptohash_ctx *ctx, const uint8 *data, size_t len)
* pg_cryptohash_final
*
* Finalize a hash context. Note that this implementation is designed
- * to never fail, so this always returns 0 except if the caller has
- * given a NULL context.
+ * to never fail, but note that this would fail if the destination buffer
+ * is not large enough.
*/
int
-pg_cryptohash_final(pg_cryptohash_ctx *ctx, uint8 *dest)
+pg_cryptohash_final(pg_cryptohash_ctx *ctx, uint8 *dest, size_t len)
{
if (ctx == NULL)
return -1;
@@ -173,21 +173,33 @@ pg_cryptohash_final(pg_cryptohash_ctx *ctx, uint8 *dest)
switch (ctx->type)
{
case PG_MD5:
+ if (len < MD5_DIGEST_LENGTH)
+ return -1;
pg_md5_final(&ctx->data.md5, dest);
break;
case PG_SHA1:
+ if (len < SHA1_DIGEST_LENGTH)
+ return -1;
pg_sha1_final(&ctx->data.sha1, dest);
break;
case PG_SHA224:
+ if (len < PG_SHA224_DIGEST_LENGTH)
+ return -1;
pg_sha224_final(&ctx->data.sha224, dest);
break;
case PG_SHA256:
+ if (len < PG_SHA256_DIGEST_LENGTH)
+ return -1;
pg_sha256_final(&ctx->data.sha256, dest);
break;
case PG_SHA384:
+ if (len < PG_SHA384_DIGEST_LENGTH)
+ return -1;
pg_sha384_final(&ctx->data.sha384, dest);
break;
case PG_SHA512:
+ if (len < PG_SHA512_DIGEST_LENGTH)
+ return -1;
pg_sha512_final(&ctx->data.sha512, dest);
break;
}
diff --git a/src/common/cryptohash_openssl.c b/src/common/cryptohash_openssl.c
index 006e867403..643cc7aea2 100644
--- a/src/common/cryptohash_openssl.c
+++ b/src/common/cryptohash_openssl.c
@@ -24,6 +24,9 @@
#include <openssl/evp.h>
#include "common/cryptohash.h"
+#include "common/md5.h"
+#include "common/sha1.h"
+#include "common/sha2.h"
#ifndef FRONTEND
#include "utils/memutils.h"
#include "utils/resowner.h"
@@ -181,13 +184,41 @@ pg_cryptohash_update(pg_cryptohash_ctx *ctx, const uint8 *data, size_t len)
* Finalize a hash context. Returns 0 on success, and -1 on failure.
*/
int
-pg_cryptohash_final(pg_cryptohash_ctx *ctx, uint8 *dest)
+pg_cryptohash_final(pg_cryptohash_ctx *ctx, uint8 *dest, size_t len)
{
int status = 0;
if (ctx == NULL)
return -1;
+ switch (ctx->type)
+ {
+ case PG_MD5:
+ if (len < MD5_DIGEST_LENGTH)
+ return -1;
+ break;
+ case PG_SHA1:
+ if (len < SHA1_DIGEST_LENGTH)
+ return -1;
+ break;
+ case PG_SHA224:
+ if (len < PG_SHA224_DIGEST_LENGTH)
+ return -1;
+ break;
+ case PG_SHA256:
+ if (len < PG_SHA256_DIGEST_LENGTH)
+ return -1;
+ break;
+ case PG_SHA384:
+ if (len < PG_SHA384_DIGEST_LENGTH)
+ return -1;
+ break;
+ case PG_SHA512:
+ if (len < PG_SHA512_DIGEST_LENGTH)
+ return -1;
+ break;
+ }
+
status = EVP_DigestFinal_ex(ctx->evpctx, dest, 0);
/* OpenSSL internals return 1 on success, 0 on failure */
diff --git a/src/common/md5_common.c b/src/common/md5_common.c
index b01c95ebb6..6a7f57031e 100644
--- a/src/common/md5_common.c
+++ b/src/common/md5_common.c
@@ -78,7 +78,8 @@ pg_md5_hash(const void *buff, size_t len, char *hexsum)
if (pg_cryptohash_init(ctx) < 0 ||
pg_cryptohash_update(ctx, buff, len) < 0 ||
- pg_cryptohash_final(ctx, sum) < 0)
+ pg_cryptohash_final(ctx, sum,
+ sizeof(sum) - 1) < 0)
{
pg_cryptohash_free(ctx);
return false;
@@ -100,7 +101,7 @@ pg_md5_binary(const void *buff, size_t len, void *outbuf)
if (pg_cryptohash_init(ctx) < 0 ||
pg_cryptohash_update(ctx, buff, len) < 0 ||
- pg_cryptohash_final(ctx, outbuf) < 0)
+ pg_cryptohash_final(ctx, outbuf, MD5_DIGEST_LENGTH) < 0)
{
pg_cryptohash_free(ctx);
return false;
diff --git a/src/common/scram-common.c b/src/common/scram-common.c
index 3f406d4e4d..7ac5810cf6 100644
--- a/src/common/scram-common.c
+++ b/src/common/scram-common.c
@@ -51,7 +51,8 @@ scram_HMAC_init(scram_HMAC_ctx *ctx, const uint8 *key, int keylen)
return -1;
if (pg_cryptohash_init(sha256_ctx) < 0 ||
pg_cryptohash_update(sha256_ctx, key, keylen) < 0 ||
- pg_cryptohash_final(sha256_ctx, keybuf) < 0)
+ pg_cryptohash_final(sha256_ctx, keybuf,
+ sizeof(keybuf) - 1) < 0)
{
pg_cryptohash_free(sha256_ctx);
return -1;
@@ -106,13 +107,14 @@ scram_HMAC_update(scram_HMAC_ctx *ctx, const char *str, int slen)
* The hash function used is SHA-256. Returns 0 on success, -1 on failure.
*/
int
-scram_HMAC_final(uint8 *result, scram_HMAC_ctx *ctx)
+scram_HMAC_final(scram_HMAC_ctx *ctx, uint8 *result)
{
uint8 h[SCRAM_KEY_LEN];
Assert(ctx->sha256ctx != NULL);
- if (pg_cryptohash_final(ctx->sha256ctx, h) < 0)
+ if (pg_cryptohash_final(ctx->sha256ctx, h,
+ sizeof(h) - 1) < 0)
{
pg_cryptohash_free(ctx->sha256ctx);
return -1;
@@ -122,7 +124,8 @@ scram_HMAC_final(uint8 *result, scram_HMAC_ctx *ctx)
if (pg_cryptohash_init(ctx->sha256ctx) < 0 ||
pg_cryptohash_update(ctx->sha256ctx, ctx->k_opad, SHA256_HMAC_B) < 0 ||
pg_cryptohash_update(ctx->sha256ctx, h, SCRAM_KEY_LEN) < 0 ||
- pg_cryptohash_final(ctx->sha256ctx, result) < 0)
+ pg_cryptohash_final(ctx->sha256ctx, result,
+ sizeof(result) - 1) < 0)
{
pg_cryptohash_free(ctx->sha256ctx);
return -1;
@@ -161,7 +164,7 @@ scram_SaltedPassword(const char *password,
if (scram_HMAC_init(&hmac_ctx, (uint8 *) password, password_len) < 0 ||
scram_HMAC_update(&hmac_ctx, salt, saltlen) < 0 ||
scram_HMAC_update(&hmac_ctx, (char *) &one, sizeof(uint32)) < 0 ||
- scram_HMAC_final(Ui_prev, &hmac_ctx) < 0)
+ scram_HMAC_final(&hmac_ctx, Ui_prev) < 0)
{
return -1;
}
@@ -173,7 +176,7 @@ scram_SaltedPassword(const char *password,
{
if (scram_HMAC_init(&hmac_ctx, (uint8 *) password, password_len) < 0 ||
scram_HMAC_update(&hmac_ctx, (const char *) Ui_prev, SCRAM_KEY_LEN) < 0 ||
- scram_HMAC_final(Ui, &hmac_ctx) < 0)
+ scram_HMAC_final(&hmac_ctx, Ui) < 0)
{
return -1;
}
@@ -202,7 +205,7 @@ scram_H(const uint8 *input, int len, uint8 *result)
if (pg_cryptohash_init(ctx) < 0 ||
pg_cryptohash_update(ctx, input, len) < 0 ||
- pg_cryptohash_final(ctx, result) < 0)
+ pg_cryptohash_final(ctx, result, SCRAM_KEY_LEN) < 0)
{
pg_cryptohash_free(ctx);
return -1;
@@ -222,7 +225,7 @@ scram_ClientKey(const uint8 *salted_password, uint8 *result)
if (scram_HMAC_init(&ctx, salted_password, SCRAM_KEY_LEN) < 0 ||
scram_HMAC_update(&ctx, "Client Key", strlen("Client Key")) < 0 ||
- scram_HMAC_final(result, &ctx) < 0)
+ scram_HMAC_final(&ctx, result) < 0)
{
return -1;
}
@@ -240,7 +243,7 @@ scram_ServerKey(const uint8 *salted_password, uint8 *result)
if (scram_HMAC_init(&ctx, salted_password, SCRAM_KEY_LEN) < 0 ||
scram_HMAC_update(&ctx, "Server Key", strlen("Server Key")) < 0 ||
- scram_HMAC_final(result, &ctx) < 0)
+ scram_HMAC_final(&ctx, result) < 0)
{
return -1;
}
diff --git a/src/include/common/cryptohash.h b/src/include/common/cryptohash.h
index 32d7784ca5..541dc844c8 100644
--- a/src/include/common/cryptohash.h
+++ b/src/include/common/cryptohash.h
@@ -32,7 +32,7 @@ typedef struct pg_cryptohash_ctx pg_cryptohash_ctx;
extern pg_cryptohash_ctx *pg_cryptohash_create(pg_cryptohash_type type);
extern int pg_cryptohash_init(pg_cryptohash_ctx *ctx);
extern int pg_cryptohash_update(pg_cryptohash_ctx *ctx, const uint8 *data, size_t len);
-extern int pg_cryptohash_final(pg_cryptohash_ctx *ctx, uint8 *dest);
+extern int pg_cryptohash_final(pg_cryptohash_ctx *ctx, uint8 *dest, size_t len);
extern void pg_cryptohash_free(pg_cryptohash_ctx *ctx);
#endif /* PG_CRYPTOHASH_H */
diff --git a/src/include/common/scram-common.h b/src/include/common/scram-common.h
index 9d684b41e8..9d7d1171b5 100644
--- a/src/include/common/scram-common.h
+++ b/src/include/common/scram-common.h
@@ -57,7 +57,7 @@ typedef struct
extern int scram_HMAC_init(scram_HMAC_ctx *ctx, const uint8 *key, int keylen);
extern int scram_HMAC_update(scram_HMAC_ctx *ctx, const char *str, int slen);
-extern int scram_HMAC_final(uint8 *result, scram_HMAC_ctx *ctx);
+extern int scram_HMAC_final(scram_HMAC_ctx *ctx, uint8 *result);
extern int scram_SaltedPassword(const char *password, const char *salt,
int saltlen, int iterations, uint8 *result);
diff --git a/src/interfaces/libpq/fe-auth-scram.c b/src/interfaces/libpq/fe-auth-scram.c
index 002469540a..f425140170 100644
--- a/src/interfaces/libpq/fe-auth-scram.c
+++ b/src/interfaces/libpq/fe-auth-scram.c
@@ -798,7 +798,7 @@ calculate_client_proof(fe_scram_state *state,
scram_HMAC_update(&ctx,
client_final_message_without_proof,
strlen(client_final_message_without_proof)) < 0 ||
- scram_HMAC_final(ClientSignature, &ctx) < 0)
+ scram_HMAC_final(&ctx, ClientSignature) < 0)
{
return false;
}
@@ -836,7 +836,7 @@ verify_server_signature(fe_scram_state *state, bool *match)
scram_HMAC_update(&ctx,
state->client_final_message_without_proof,
strlen(state->client_final_message_without_proof)) < 0 ||
- scram_HMAC_final(expected_ServerSignature, &ctx) < 0)
+ scram_HMAC_final(&ctx, expected_ServerSignature) < 0)
{
return false;
}