summaryrefslogtreecommitdiff
path: root/contrib/pgcrypto/crypt-gensalt.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/pgcrypto/crypt-gensalt.c')
-rw-r--r--contrib/pgcrypto/crypt-gensalt.c82
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);
+}