mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Add modern SHA-2 based password hashes to pgcrypto.
This adapts the publicly available reference implementation on https://www.akkadia.org/drepper/SHA-crypt.txt and adds the new hash algorithms sha256crypt and sha512crypt to crypt() and gen_salt() respectively. Author: Bernd Helmle <mailings@oopsware.de> Reviewed-by: Japin Li <japinli@hotmail.com> Discussion: https://postgr.es/m/c763235a2757e2f5f9e3e27268b9028349cef659.camel@oopsware.de
This commit is contained in:
@ -185,3 +185,85 @@ _crypt_gensalt_blowfish_rn(unsigned long count,
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper for _crypt_gensalt_sha256_rn and _crypt_gensalt_sha512_rn
|
||||
*/
|
||||
static char *
|
||||
_crypt_gensalt_sha(unsigned long count,
|
||||
const char *input, int size, char *output, int output_size)
|
||||
{
|
||||
char *s_ptr = output;
|
||||
unsigned int result_bufsize = PX_SHACRYPT_SALT_BUF_LEN;
|
||||
int rc;
|
||||
|
||||
/* output buffer must be allocated with PX_MAX_SALT_LEN bytes */
|
||||
if (PX_MAX_SALT_LEN < result_bufsize)
|
||||
ereport(ERROR,
|
||||
errcode(ERRCODE_SYNTAX_ERROR),
|
||||
errmsg("invalid size of salt"));
|
||||
|
||||
/*
|
||||
* Care must be taken to not exceed the buffer size allocated for the
|
||||
* input character buffer.
|
||||
*/
|
||||
if ((PX_SHACRYPT_SALT_MAX_LEN != size) || (output_size < size))
|
||||
ereport(ERROR,
|
||||
errcode(ERRCODE_INTERNAL_ERROR),
|
||||
errmsg("invalid length of salt buffer"));
|
||||
|
||||
/* Skip magic bytes, set by callers */
|
||||
s_ptr += 3;
|
||||
if ((rc = pg_snprintf(s_ptr, 18, "rounds=%ld$", count)) <= 0)
|
||||
ereport(ERROR,
|
||||
errcode(ERRCODE_INTERNAL_ERROR),
|
||||
errmsg("cannot format salt string"));
|
||||
|
||||
/* s_ptr should now be positioned at the start of the salt string */
|
||||
s_ptr += rc;
|
||||
|
||||
/*
|
||||
* Normalize salt string
|
||||
*
|
||||
* size of input buffer was checked above to not exceed
|
||||
* PX_SHACRYPT_SALT_LEN_MAX.
|
||||
*/
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
*s_ptr = _crypt_itoa64[input[i] & 0x3f];
|
||||
s_ptr++;
|
||||
}
|
||||
|
||||
/* We're done */
|
||||
return output;
|
||||
}
|
||||
|
||||
/* gen_list->gen function for sha512 */
|
||||
char *
|
||||
_crypt_gensalt_sha512_rn(unsigned long count,
|
||||
char const *input, int size,
|
||||
char *output, int output_size)
|
||||
{
|
||||
memset(output, 0, output_size);
|
||||
/* set magic byte for sha512crypt */
|
||||
output[0] = '$';
|
||||
output[1] = '6';
|
||||
output[2] = '$';
|
||||
|
||||
return _crypt_gensalt_sha(count, input, size, output, output_size);
|
||||
}
|
||||
|
||||
/* gen_list->gen function for sha256 */
|
||||
char *
|
||||
_crypt_gensalt_sha256_rn(unsigned long count,
|
||||
const char *input, int size,
|
||||
char *output, int output_size)
|
||||
{
|
||||
memset(output, 0, output_size);
|
||||
/* set magic byte for sha256crypt */
|
||||
output[0] = '$';
|
||||
output[1] = '5';
|
||||
output[2] = '$';
|
||||
|
||||
return _crypt_gensalt_sha(count, input, size, output, output_size);
|
||||
}
|
||||
|
Reference in New Issue
Block a user