* This method is mostly copied from pg_be_scram_build_secret in PG. The only substantial change * is that we use a default salt length of 28 as opposed to 16 used by PG. This is to ensure * compatiblity with drivers that expect a salt length of 28. */
| 1296 | * compatiblity with drivers that expect a salt length of 28. |
| 1297 | */ |
| 1298 | static char * |
| 1299 | PrehashPassword(const char *password) |
| 1300 | { |
| 1301 | char *prep_password; |
| 1302 | pg_saslprep_rc rc; |
| 1303 | char_uint8_compat saltbuf[SCRAM_MAX_SALT_LEN]; |
| 1304 | char *result; |
| 1305 | const char *errstr = NULL; |
| 1306 | |
| 1307 | /* |
| 1308 | * Validate that the default salt length is not greater than the max salt length allowed |
| 1309 | */ |
| 1310 | if (ScramDefaultSaltLen > SCRAM_MAX_SALT_LEN) |
| 1311 | { |
| 1312 | ereport(ERROR, (errcode(ERRCODE_DOCUMENTDB_BADVALUE), |
| 1313 | errmsg("Salt length value is invalid."))); |
| 1314 | } |
| 1315 | |
| 1316 | /* |
| 1317 | * Normalize the password with SASLprep. If that doesn't work, because |
| 1318 | * the password isn't valid UTF-8 or contains prohibited characters, just |
| 1319 | * proceed with the original password. (See comments at top of file.) |
| 1320 | */ |
| 1321 | rc = pg_saslprep(password, &prep_password); |
| 1322 | if (rc == SASLPREP_SUCCESS) |
| 1323 | { |
| 1324 | password = (const char *) prep_password; |
| 1325 | } |
| 1326 | |
| 1327 | /* Generate random salt */ |
| 1328 | if (!pg_strong_random(saltbuf, ScramDefaultSaltLen)) |
| 1329 | { |
| 1330 | ereport(ERROR, |
| 1331 | (errcode(ERRCODE_INTERNAL_ERROR), |
| 1332 | errmsg("Could not generate random salt."))); |
| 1333 | } |
| 1334 | |
| 1335 | #if PG_VERSION_NUM >= 160000 /* PostgreSQL 16.0 or higher */ |
| 1336 | result = scram_build_secret(PG_SHA256, SCRAM_SHA_256_KEY_LEN, |
| 1337 | saltbuf, ScramDefaultSaltLen, |
| 1338 | scram_sha_256_iterations, password, |
| 1339 | &errstr); |
| 1340 | #else |
| 1341 | result = scram_build_secret(saltbuf, ScramDefaultSaltLen, |
| 1342 | SCRAM_DEFAULT_ITERATIONS, password, |
| 1343 | &errstr); |
| 1344 | #endif |
| 1345 | |
| 1346 | if (prep_password) |
| 1347 | { |
| 1348 | pfree(prep_password); |
| 1349 | } |
| 1350 | |
| 1351 | return result; |
| 1352 | } |
| 1353 | |
| 1354 | |
| 1355 | /* |
no outgoing calls
no test coverage detected