Skip to content

Commit 3889016

Browse files
author
Commitfest Bot
committed
[CF 5481] Modern SHA2- based password hashes for pgcrypto
This branch was automatically generated by a robot using patches from an email thread registered at: https://commitfest.postgresql.org/patch/5481 The branch will be overwritten each time a new patch version is posted to the thread, and also periodically to check for bitrot caused by changes on the master branch. Patch(es): https://www.postgresql.org/message-id/[email protected] Author(s): Bernd Helmle
2 parents dbd437e + 556a1b3 commit 3889016

File tree

9 files changed

+1164
-2
lines changed

9 files changed

+1164
-2
lines changed

contrib/pgcrypto/Makefile

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ OBJS = \
1111
crypt-des.o \
1212
crypt-gensalt.o \
1313
crypt-md5.o \
14+
crypt-sha.o \
1415
mbuf.o \
1516
openssl.o \
1617
pgcrypto.o \
@@ -43,7 +44,7 @@ REGRESS = init md5 sha1 hmac-md5 hmac-sha1 blowfish rijndael \
4344
sha2 des 3des cast5 \
4445
crypt-des crypt-md5 crypt-blowfish crypt-xdes \
4546
pgp-armor pgp-decrypt pgp-encrypt pgp-encrypt-md5 $(CF_PGP_TESTS) \
46-
pgp-pubkey-decrypt pgp-pubkey-encrypt pgp-info
47+
pgp-pubkey-decrypt pgp-pubkey-encrypt pgp-info crypt-shacrypt
4748

4849
ifdef USE_PGXS
4950
PG_CONFIG = pg_config

contrib/pgcrypto/crypt-gensalt.c

+84
Original file line numberDiff line numberDiff line change
@@ -185,3 +185,87 @@ _crypt_gensalt_blowfish_rn(unsigned long count,
185185

186186
return output;
187187
}
188+
189+
static char *
190+
_crypt_gensalt_sha(unsigned long count,
191+
const char *input, int size, char *output, int output_size)
192+
{
193+
char * s_ptr = output;
194+
unsigned int result_bufsize = PX_SHACRYPT_SALT_BUF_LEN;
195+
int rc;
196+
197+
/* output buffer must be allocated with PX_MAX_SALT_LEN bytes */
198+
if (PX_MAX_SALT_LEN < result_bufsize)
199+
{
200+
ereport(ERROR,
201+
(errcode(ERRCODE_SYNTAX_ERROR),
202+
errmsg("invalid size of salt")));
203+
}
204+
205+
/*
206+
* Care must be taken to not exceed the buffer size allocated for
207+
* the input character buffer.
208+
*/
209+
if ((PX_SHACRYPT_SALT_MAX_LEN != size)
210+
|| (output_size < size))
211+
{
212+
ereport(ERROR,
213+
(errcode(ERRCODE_INTERNAL_ERROR),
214+
errmsg("invalid length of salt buffer")));
215+
}
216+
217+
/* Skip magic bytes, set by callers */
218+
s_ptr += 3;
219+
if ((rc = pg_snprintf(s_ptr, 18, "rounds=%ld$", count)) <= 0)
220+
{
221+
ereport(ERROR,
222+
(errcode(ERRCODE_INTERNAL_ERROR),
223+
errmsg("cannot format salt string")));
224+
}
225+
226+
/* s_ptr should now be positioned at the start of the salt string */
227+
s_ptr += rc;
228+
229+
/*
230+
* Normalize salt string
231+
*
232+
* size of input buffer was checked above to
233+
* not exceed PX_SHACRYPT_SALT_LEN_MAX.
234+
*/
235+
for (int i = 0; i < size; i++)
236+
{
237+
*s_ptr = _crypt_itoa64[input[i] & 0x3f];
238+
s_ptr++;
239+
}
240+
241+
/* We're done */
242+
return output;
243+
}
244+
245+
char *
246+
_crypt_gensalt_sha512_rn(unsigned long count,
247+
char const *input, int size,
248+
char *output, int output_size)
249+
{
250+
memset(output, 0, output_size);
251+
/* set magic byte for sha512crypt */
252+
output[0] = '$';
253+
output[1] = '6';
254+
output[2] = '$';
255+
256+
return _crypt_gensalt_sha(count, input, size, output, output_size);
257+
}
258+
259+
char *
260+
_crypt_gensalt_sha256_rn(unsigned long count,
261+
const char *input, int size,
262+
char *output, int output_size)
263+
{
264+
memset(output, 0, output_size);
265+
/* set magic byte for sha256crypt */
266+
output[0] = '$';
267+
output[1] = '5';
268+
output[2] = '$';
269+
270+
return _crypt_gensalt_sha(count, input, size, output, output_size);
271+
}

0 commit comments

Comments
 (0)