diff options
author | Michael Paquier <michael@paquier.xyz> | 2020-12-04 12:58:44 +0900 |
---|---|---|
committer | Michael Paquier <michael@paquier.xyz> | 2020-12-04 12:58:44 +0900 |
commit | bd94a9c04e04bb3b626e88981a50fcca2bd99d60 (patch) | |
tree | fc386a6cd043da9d074ac9818b36def2c719e7ee /src/backend/utils/adt/cryptohashfuncs.c | |
parent | 4f48a6fbe2b28d8281dbbfa2d334fa2ed8472734 (diff) | |
download | postgresql-bd94a9c04e04bb3b626e88981a50fcca2bd99d60.tar.gz |
Rename cryptohashes.c to cryptohashfuncs.c
87ae969 has created two new files called cryptohash{_openssl}.c in
src/common/, whose names overlap with the existing backend file called
cryptohashes.c dedicated to the SQL wrappers for SHA2 and MD5. This
file is renamed to cryptohashfuncs.c to be more consistent with the
surroundings and reduce the confusion with the new cryptohash interface
of src/common/.
Author: Michael Paquier
Reviewed-by: Daniel Gustafsson
Discussion: https://postgr.es/m/X8hHhaQgbMbW+aGU@paquier.xyz
Diffstat (limited to 'src/backend/utils/adt/cryptohashfuncs.c')
-rw-r--r-- | src/backend/utils/adt/cryptohashfuncs.c | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/src/backend/utils/adt/cryptohashfuncs.c b/src/backend/utils/adt/cryptohashfuncs.c new file mode 100644 index 0000000000..47bc0b3482 --- /dev/null +++ b/src/backend/utils/adt/cryptohashfuncs.c @@ -0,0 +1,190 @@ +/*------------------------------------------------------------------------- + * + * cryptohashfuncs.c + * Cryptographic hash functions + * + * Portions Copyright (c) 2018-2020, PostgreSQL Global Development Group + * + * + * IDENTIFICATION + * src/backend/utils/adt/cryptohashfuncs.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "common/cryptohash.h" +#include "common/md5.h" +#include "common/sha2.h" +#include "utils/builtins.h" + + +/* + * MD5 + */ + +/* MD5 produces a 16 byte (128 bit) hash; double it for hex */ +#define MD5_HASH_LEN 32 + +/* + * Create an MD5 hash of a text value and return it as hex string. + */ +Datum +md5_text(PG_FUNCTION_ARGS) +{ + text *in_text = PG_GETARG_TEXT_PP(0); + size_t len; + char hexsum[MD5_HASH_LEN + 1]; + + /* Calculate the length of the buffer using varlena metadata */ + len = VARSIZE_ANY_EXHDR(in_text); + + /* get the hash result */ + if (pg_md5_hash(VARDATA_ANY(in_text), len, hexsum) == false) + ereport(ERROR, + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("out of memory"))); + + /* convert to text and return it */ + PG_RETURN_TEXT_P(cstring_to_text(hexsum)); +} + +/* + * Create an MD5 hash of a bytea value and return it as a hex string. + */ +Datum +md5_bytea(PG_FUNCTION_ARGS) +{ + bytea *in = PG_GETARG_BYTEA_PP(0); + size_t len; + char hexsum[MD5_HASH_LEN + 1]; + + len = VARSIZE_ANY_EXHDR(in); + if (pg_md5_hash(VARDATA_ANY(in), len, hexsum) == false) + ereport(ERROR, + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("out of memory"))); + + PG_RETURN_TEXT_P(cstring_to_text(hexsum)); +} + + +/* + * SHA-2 variants + */ + +Datum +sha224_bytea(PG_FUNCTION_ARGS) +{ + bytea *in = PG_GETARG_BYTEA_PP(0); + const uint8 *data; + size_t len; + pg_cryptohash_ctx *ctx; + unsigned char buf[PG_SHA224_DIGEST_LENGTH]; + bytea *result; + + len = VARSIZE_ANY_EXHDR(in); + data = (unsigned char *) VARDATA_ANY(in); + + ctx = pg_cryptohash_create(PG_SHA224); + if (pg_cryptohash_init(ctx) < 0) + elog(ERROR, "could not initialize %s context", "SHA224"); + if (pg_cryptohash_update(ctx, data, len) < 0) + elog(ERROR, "could not update %s context", "SHA224"); + if (pg_cryptohash_final(ctx, buf) < 0) + elog(ERROR, "could not finalize %s context", "SHA224"); + pg_cryptohash_free(ctx); + + result = palloc(sizeof(buf) + VARHDRSZ); + SET_VARSIZE(result, sizeof(buf) + VARHDRSZ); + memcpy(VARDATA(result), buf, sizeof(buf)); + + PG_RETURN_BYTEA_P(result); +} + +Datum +sha256_bytea(PG_FUNCTION_ARGS) +{ + bytea *in = PG_GETARG_BYTEA_PP(0); + const uint8 *data; + size_t len; + pg_cryptohash_ctx *ctx; + unsigned char buf[PG_SHA256_DIGEST_LENGTH]; + bytea *result; + + len = VARSIZE_ANY_EXHDR(in); + data = (unsigned char *) VARDATA_ANY(in); + + ctx = pg_cryptohash_create(PG_SHA256); + if (pg_cryptohash_init(ctx) < 0) + elog(ERROR, "could not initialize %s context", "SHA256"); + if (pg_cryptohash_update(ctx, data, len) < 0) + elog(ERROR, "could not update %s context", "SHA256"); + if (pg_cryptohash_final(ctx, buf) < 0) + elog(ERROR, "could not finalize %s context", "SHA256"); + pg_cryptohash_free(ctx); + + result = palloc(sizeof(buf) + VARHDRSZ); + SET_VARSIZE(result, sizeof(buf) + VARHDRSZ); + memcpy(VARDATA(result), buf, sizeof(buf)); + + PG_RETURN_BYTEA_P(result); +} + +Datum +sha384_bytea(PG_FUNCTION_ARGS) +{ + bytea *in = PG_GETARG_BYTEA_PP(0); + const uint8 *data; + size_t len; + pg_cryptohash_ctx *ctx; + unsigned char buf[PG_SHA384_DIGEST_LENGTH]; + bytea *result; + + len = VARSIZE_ANY_EXHDR(in); + data = (unsigned char *) VARDATA_ANY(in); + + ctx = pg_cryptohash_create(PG_SHA384); + if (pg_cryptohash_init(ctx) < 0) + elog(ERROR, "could not initialize %s context", "SHA384"); + if (pg_cryptohash_update(ctx, data, len) < 0) + elog(ERROR, "could not update %s context", "SHA384"); + if (pg_cryptohash_final(ctx, buf) < 0) + elog(ERROR, "could not finalize %s context", "SHA384"); + pg_cryptohash_free(ctx); + + result = palloc(sizeof(buf) + VARHDRSZ); + SET_VARSIZE(result, sizeof(buf) + VARHDRSZ); + memcpy(VARDATA(result), buf, sizeof(buf)); + + PG_RETURN_BYTEA_P(result); +} + +Datum +sha512_bytea(PG_FUNCTION_ARGS) +{ + bytea *in = PG_GETARG_BYTEA_PP(0); + const uint8 *data; + size_t len; + pg_cryptohash_ctx *ctx; + unsigned char buf[PG_SHA512_DIGEST_LENGTH]; + bytea *result; + + len = VARSIZE_ANY_EXHDR(in); + data = (unsigned char *) VARDATA_ANY(in); + + ctx = pg_cryptohash_create(PG_SHA512); + if (pg_cryptohash_init(ctx) < 0) + elog(ERROR, "could not initialize %s context", "SHA512"); + if (pg_cryptohash_update(ctx, data, len) < 0) + elog(ERROR, "could not update %s context", "SHA512"); + if (pg_cryptohash_final(ctx, buf) < 0) + elog(ERROR, "could not finalize %s context", "SHA512"); + pg_cryptohash_free(ctx); + + result = palloc(sizeof(buf) + VARHDRSZ); + SET_VARSIZE(result, sizeof(buf) + VARHDRSZ); + memcpy(VARDATA(result), buf, sizeof(buf)); + + PG_RETURN_BYTEA_P(result); +} |