diff options
Diffstat (limited to 'contrib/pgcrypto/crypt-gensalt.c')
-rw-r--r-- | contrib/pgcrypto/crypt-gensalt.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/contrib/pgcrypto/crypt-gensalt.c b/contrib/pgcrypto/crypt-gensalt.c index 740f3612532..ef68ae0e49e 100644 --- a/contrib/pgcrypto/crypt-gensalt.c +++ b/contrib/pgcrypto/crypt-gensalt.c @@ -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); +} |