Skip to content

Commit f854c69

Browse files
committed
Refactor SQL functions of SHA-2 in cryptohashfuncs.c
The same code pattern was repeated four times when compiling a SHA-2 hash. This refactoring has the advantage to issue a compilation warning if a new value is added to pg_cryptohash_type, so as anybody doing an addition in this area would need to consider if support for a new SQL function is needed or not. Author: Sehrope Sarkuni, Michael Paquier Discussion: https://postgr.es/m/YA7DvLRn2xnTgsMc@paquier.xyz
1 parent e19594c commit f854c69

File tree

1 file changed

+54
-84
lines changed

1 file changed

+54
-84
lines changed

src/backend/utils/adt/cryptohashfuncs.c

Lines changed: 54 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -68,123 +68,93 @@ md5_bytea(PG_FUNCTION_ARGS)
6868
PG_RETURN_TEXT_P(cstring_to_text(hexsum));
6969
}
7070

71-
7271
/*
73-
* SHA-2 variants
72+
* Internal routine to compute a cryptohash with the given bytea input.
7473
*/
75-
76-
Datum
77-
sha224_bytea(PG_FUNCTION_ARGS)
74+
static inline bytea *
75+
cryptohash_internal(pg_cryptohash_type type, bytea *input)
7876
{
79-
bytea *in = PG_GETARG_BYTEA_PP(0);
8077
const uint8 *data;
78+
const char *typestr = NULL;
79+
int digest_len = 0;
8180
size_t len;
8281
pg_cryptohash_ctx *ctx;
83-
unsigned char buf[PG_SHA224_DIGEST_LENGTH];
8482
bytea *result;
8583

86-
len = VARSIZE_ANY_EXHDR(in);
87-
data = (unsigned char *) VARDATA_ANY(in);
88-
89-
ctx = pg_cryptohash_create(PG_SHA224);
84+
switch (type)
85+
{
86+
case PG_SHA224:
87+
typestr = "SHA224";
88+
digest_len = PG_SHA224_DIGEST_LENGTH;
89+
break;
90+
case PG_SHA256:
91+
typestr = "SHA256";
92+
digest_len = PG_SHA256_DIGEST_LENGTH;
93+
break;
94+
case PG_SHA384:
95+
typestr = "SHA384";
96+
digest_len = PG_SHA384_DIGEST_LENGTH;
97+
break;
98+
case PG_SHA512:
99+
typestr = "SHA512";
100+
digest_len = PG_SHA512_DIGEST_LENGTH;
101+
break;
102+
case PG_MD5:
103+
case PG_SHA1:
104+
elog(ERROR, "unsupported cryptohash type %d", type);
105+
break;
106+
}
107+
108+
result = palloc0(digest_len + VARHDRSZ);
109+
len = VARSIZE_ANY_EXHDR(input);
110+
data = (unsigned char *) VARDATA_ANY(input);
111+
112+
ctx = pg_cryptohash_create(type);
90113
if (pg_cryptohash_init(ctx) < 0)
91-
elog(ERROR, "could not initialize %s context", "SHA224");
114+
elog(ERROR, "could not initialize %s context", typestr);
92115
if (pg_cryptohash_update(ctx, data, len) < 0)
93-
elog(ERROR, "could not update %s context", "SHA224");
94-
if (pg_cryptohash_final(ctx, buf) < 0)
95-
elog(ERROR, "could not finalize %s context", "SHA224");
116+
elog(ERROR, "could not update %s context", typestr);
117+
if (pg_cryptohash_final(ctx, (unsigned char *) VARDATA(result)) < 0)
118+
elog(ERROR, "could not finalize %s context", typestr);
96119
pg_cryptohash_free(ctx);
97120

98-
result = palloc(sizeof(buf) + VARHDRSZ);
99-
SET_VARSIZE(result, sizeof(buf) + VARHDRSZ);
100-
memcpy(VARDATA(result), buf, sizeof(buf));
121+
SET_VARSIZE(result, digest_len + VARHDRSZ);
101122

102-
PG_RETURN_BYTEA_P(result);
123+
return result;
103124
}
104125

126+
/*
127+
* SHA-2 variants
128+
*/
129+
105130
Datum
106-
sha256_bytea(PG_FUNCTION_ARGS)
131+
sha224_bytea(PG_FUNCTION_ARGS)
107132
{
108-
bytea *in = PG_GETARG_BYTEA_PP(0);
109-
const uint8 *data;
110-
size_t len;
111-
pg_cryptohash_ctx *ctx;
112-
unsigned char buf[PG_SHA256_DIGEST_LENGTH];
113-
bytea *result;
133+
bytea *result = cryptohash_internal(PG_SHA224, PG_GETARG_BYTEA_PP(0));
114134

115-
len = VARSIZE_ANY_EXHDR(in);
116-
data = (unsigned char *) VARDATA_ANY(in);
117-
118-
ctx = pg_cryptohash_create(PG_SHA256);
119-
if (pg_cryptohash_init(ctx) < 0)
120-
elog(ERROR, "could not initialize %s context", "SHA256");
121-
if (pg_cryptohash_update(ctx, data, len) < 0)
122-
elog(ERROR, "could not update %s context", "SHA256");
123-
if (pg_cryptohash_final(ctx, buf) < 0)
124-
elog(ERROR, "could not finalize %s context", "SHA256");
125-
pg_cryptohash_free(ctx);
135+
PG_RETURN_BYTEA_P(result);
136+
}
126137

127-
result = palloc(sizeof(buf) + VARHDRSZ);
128-
SET_VARSIZE(result, sizeof(buf) + VARHDRSZ);
129-
memcpy(VARDATA(result), buf, sizeof(buf));
138+
Datum
139+
sha256_bytea(PG_FUNCTION_ARGS)
140+
{
141+
bytea *result = cryptohash_internal(PG_SHA256, PG_GETARG_BYTEA_PP(0));
130142

131143
PG_RETURN_BYTEA_P(result);
132144
}
133145

134146
Datum
135147
sha384_bytea(PG_FUNCTION_ARGS)
136148
{
137-
bytea *in = PG_GETARG_BYTEA_PP(0);
138-
const uint8 *data;
139-
size_t len;
140-
pg_cryptohash_ctx *ctx;
141-
unsigned char buf[PG_SHA384_DIGEST_LENGTH];
142-
bytea *result;
143-
144-
len = VARSIZE_ANY_EXHDR(in);
145-
data = (unsigned char *) VARDATA_ANY(in);
146-
147-
ctx = pg_cryptohash_create(PG_SHA384);
148-
if (pg_cryptohash_init(ctx) < 0)
149-
elog(ERROR, "could not initialize %s context", "SHA384");
150-
if (pg_cryptohash_update(ctx, data, len) < 0)
151-
elog(ERROR, "could not update %s context", "SHA384");
152-
if (pg_cryptohash_final(ctx, buf) < 0)
153-
elog(ERROR, "could not finalize %s context", "SHA384");
154-
pg_cryptohash_free(ctx);
155-
156-
result = palloc(sizeof(buf) + VARHDRSZ);
157-
SET_VARSIZE(result, sizeof(buf) + VARHDRSZ);
158-
memcpy(VARDATA(result), buf, sizeof(buf));
149+
bytea *result = cryptohash_internal(PG_SHA384, PG_GETARG_BYTEA_PP(0));
159150

160151
PG_RETURN_BYTEA_P(result);
161152
}
162153

163154
Datum
164155
sha512_bytea(PG_FUNCTION_ARGS)
165156
{
166-
bytea *in = PG_GETARG_BYTEA_PP(0);
167-
const uint8 *data;
168-
size_t len;
169-
pg_cryptohash_ctx *ctx;
170-
unsigned char buf[PG_SHA512_DIGEST_LENGTH];
171-
bytea *result;
172-
173-
len = VARSIZE_ANY_EXHDR(in);
174-
data = (unsigned char *) VARDATA_ANY(in);
175-
176-
ctx = pg_cryptohash_create(PG_SHA512);
177-
if (pg_cryptohash_init(ctx) < 0)
178-
elog(ERROR, "could not initialize %s context", "SHA512");
179-
if (pg_cryptohash_update(ctx, data, len) < 0)
180-
elog(ERROR, "could not update %s context", "SHA512");
181-
if (pg_cryptohash_final(ctx, buf) < 0)
182-
elog(ERROR, "could not finalize %s context", "SHA512");
183-
pg_cryptohash_free(ctx);
184-
185-
result = palloc(sizeof(buf) + VARHDRSZ);
186-
SET_VARSIZE(result, sizeof(buf) + VARHDRSZ);
187-
memcpy(VARDATA(result), buf, sizeof(buf));
157+
bytea *result = cryptohash_internal(PG_SHA512, PG_GETARG_BYTEA_PP(0));
188158

189159
PG_RETURN_BYTEA_P(result);
190160
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy