Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+54-84
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)