PostgreSQL Source Code git master
Loading...
Searching...
No Matches
scram.h File Reference
#include "common/cryptohash.h"
#include "lib/stringinfo.h"
#include "libpq/libpq-be.h"
#include "libpq/sasl.h"
Include dependency graph for scram.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

charpg_be_scram_build_secret (const char *password)
 
bool parse_scram_secret (const char *secret, int *iterations, pg_cryptohash_type *hash_type, int *key_length, char **salt, uint8 *stored_key, uint8 *server_key)
 
bool scram_verify_plain_password (const char *username, const char *password, const char *secret)
 

Variables

PGDLLIMPORT int scram_sha_256_iterations
 
PGDLLIMPORT const pg_be_sasl_mech pg_be_scram_mech
 

Function Documentation

◆ parse_scram_secret()

bool parse_scram_secret ( const char secret,
int iterations,
pg_cryptohash_type hash_type,
int key_length,
char **  salt,
uint8 stored_key,
uint8 server_key 
)
extern

Definition at line 598 of file auth-scram.c.

601{
602 char *v;
603 char *p;
604 char *scheme_str;
605 char *salt_str;
606 char *iterations_str;
607 char *storedkey_str;
608 char *serverkey_str;
609 int decoded_len;
613
614 /*
615 * The secret is of form:
616 *
617 * SCRAM-SHA-256$<iterations>:<salt>$<storedkey>:<serverkey>
618 */
619 v = pstrdup(secret);
620 scheme_str = strsep(&v, "$");
621 if (v == NULL)
622 goto invalid_secret;
623 iterations_str = strsep(&v, ":");
624 if (v == NULL)
625 goto invalid_secret;
626 salt_str = strsep(&v, "$");
627 if (v == NULL)
628 goto invalid_secret;
629 storedkey_str = strsep(&v, ":");
630 if (v == NULL)
631 goto invalid_secret;
632 serverkey_str = v;
633
634 /* Parse the fields */
635 if (strcmp(scheme_str, "SCRAM-SHA-256") != 0)
636 goto invalid_secret;
637 *hash_type = PG_SHA256;
638 *key_length = SCRAM_SHA_256_KEY_LEN;
639
640 errno = 0;
641 *iterations = strtol(iterations_str, &p, 10);
642 if (*p || errno != 0)
643 goto invalid_secret;
644
645 /*
646 * Verify that the salt is in Base64-encoded format, by decoding it,
647 * although we return the encoded version to the caller.
648 */
653 if (decoded_len < 0)
654 goto invalid_secret;
655 *salt = pstrdup(salt_str);
656
657 /*
658 * Decode StoredKey and ServerKey.
659 */
664 if (decoded_len != *key_length)
665 goto invalid_secret;
666 memcpy(stored_key, decoded_stored_buf, *key_length);
667
672 if (decoded_len != *key_length)
673 goto invalid_secret;
674 memcpy(server_key, decoded_server_buf, *key_length);
675
676 return true;
677
679 *salt = NULL;
680 return false;
681}
int pg_b64_dec_len(int srclen)
Definition base64.c:239
int pg_b64_decode(const char *src, int len, uint8 *dst, int dstlen)
Definition base64.c:116
uint8_t uint8
Definition c.h:544
@ PG_SHA256
Definition cryptohash.h:24
char * pstrdup(const char *in)
Definition mcxt.c:1781
void * palloc(Size size)
Definition mcxt.c:1387
char * strsep(char **stringp, const char *delim)
Definition strsep.c:49
static int fb(int x)
#define SCRAM_SHA_256_KEY_LEN
int iterations

References fb(), iterations, palloc(), pg_b64_dec_len(), pg_b64_decode(), PG_SHA256, pstrdup(), SCRAM_SHA_256_KEY_LEN, and strsep().

Referenced by get_password_type(), scram_init(), and scram_verify_plain_password().

◆ pg_be_scram_build_secret()

char * pg_be_scram_build_secret ( const char password)
extern

Definition at line 481 of file auth-scram.c.

482{
483 char *prep_password;
486 char *result;
487 const char *errstr = NULL;
488
489 /*
490 * Normalize the password with SASLprep. If that doesn't work, because
491 * the password isn't valid UTF-8 or contains prohibited characters, just
492 * proceed with the original password. (See comments at top of file.)
493 */
495 if (rc == SASLPREP_SUCCESS)
496 password = (const char *) prep_password;
497
498 /* Generate random salt */
502 errmsg("could not generate random salt")));
503
507 &errstr);
508
509 if (prep_password)
511
512 return result;
513}
int scram_sha_256_iterations
Definition auth-scram.c:194
int errcode(int sqlerrcode)
Definition elog.c:863
int errmsg(const char *fmt,...)
Definition elog.c:1080
#define ERROR
Definition elog.h:39
#define ereport(elevel,...)
Definition elog.h:150
void pfree(void *pointer)
Definition mcxt.c:1616
bool pg_strong_random(void *buf, size_t len)
pg_saslprep_rc pg_saslprep(const char *input, char **output)
Definition saslprep.c:1047
pg_saslprep_rc
Definition saslprep.h:21
@ SASLPREP_SUCCESS
Definition saslprep.h:22
char * scram_build_secret(pg_cryptohash_type hash_type, int key_length, const uint8 *salt, int saltlen, int iterations, const char *password, const char **errstr)
#define SCRAM_DEFAULT_SALT_LEN
static char * password
Definition streamutil.c:51

References ereport, errcode(), errmsg(), ERROR, fb(), password, pfree(), pg_saslprep(), PG_SHA256, pg_strong_random(), SASLPREP_SUCCESS, scram_build_secret(), SCRAM_DEFAULT_SALT_LEN, scram_sha_256_iterations, and SCRAM_SHA_256_KEY_LEN.

Referenced by encrypt_password().

◆ scram_verify_plain_password()

bool scram_verify_plain_password ( const char username,
const char password,
const char secret 
)
extern

Definition at line 521 of file auth-scram.c.

523{
524 char *encoded_salt;
525 uint8 *salt;
526 int saltlen;
527 int iterations;
528 int key_length = 0;
529 pg_cryptohash_type hash_type;
534 char *prep_password;
536 const char *errstr = NULL;
537
538 if (!parse_scram_secret(secret, &iterations, &hash_type, &key_length,
540 {
541 /*
542 * The password looked like a SCRAM secret, but could not be parsed.
543 */
544 ereport(LOG,
545 (errmsg("invalid SCRAM secret for user \"%s\"", username)));
546 return false;
547 }
548
550 salt = palloc(saltlen);
552 saltlen);
553 if (saltlen < 0)
554 {
555 ereport(LOG,
556 (errmsg("invalid SCRAM secret for user \"%s\"", username)));
557 return false;
558 }
559
560 /* Normalize the password */
562 if (rc == SASLPREP_SUCCESS)
564
565 /* Compute Server Key based on the user-supplied plaintext password */
566 if (scram_SaltedPassword(password, hash_type, key_length,
567 salt, saltlen, iterations,
568 salted_password, &errstr) < 0 ||
569 scram_ServerKey(salted_password, hash_type, key_length,
570 computed_key, &errstr) < 0)
571 {
572 elog(ERROR, "could not compute server key: %s", errstr);
573 }
574
575 if (prep_password)
577
578 /*
579 * Compare the secret's Server Key with the one computed from the
580 * user-supplied password.
581 */
582 return memcmp(computed_key, server_key, key_length) == 0;
583}
bool parse_scram_secret(const char *secret, int *iterations, pg_cryptohash_type *hash_type, int *key_length, char **salt, uint8 *stored_key, uint8 *server_key)
Definition auth-scram.c:598
pg_cryptohash_type
Definition cryptohash.h:20
#define LOG
Definition elog.h:31
#define elog(elevel,...)
Definition elog.h:226
static char * username
Definition initdb.c:153
int scram_ServerKey(const uint8 *salted_password, pg_cryptohash_type hash_type, int key_length, uint8 *result, const char **errstr)
int scram_SaltedPassword(const char *password, pg_cryptohash_type hash_type, int key_length, const uint8 *salt, int saltlen, int iterations, uint8 *result, const char **errstr)
#define SCRAM_MAX_KEY_LEN

References elog, ereport, errmsg(), ERROR, fb(), iterations, LOG, palloc(), parse_scram_secret(), password, pfree(), pg_b64_dec_len(), pg_b64_decode(), pg_saslprep(), SASLPREP_SUCCESS, SCRAM_MAX_KEY_LEN, scram_SaltedPassword(), scram_ServerKey(), and username.

Referenced by plain_crypt_verify().

Variable Documentation

◆ pg_be_scram_mech

PGDLLIMPORT const pg_be_sasl_mech pg_be_scram_mech
extern

Definition at line 114 of file auth-scram.c.

114 {
118
120};
static void * scram_init(Port *port, const char *selected_mech, const char *shadow_pass)
Definition auth-scram.c:238
static int scram_exchange(void *opaq, const char *input, int inputlen, char **output, int *outputlen, const char **logdetail)
Definition auth-scram.c:350
static void scram_get_mechanisms(Port *port, StringInfo buf)
Definition auth-scram.c:204
#define PG_MAX_SASL_MESSAGE_LENGTH
Definition sasl.h:35

Referenced by CheckPWChallengeAuth().

◆ scram_sha_256_iterations

PGDLLIMPORT int scram_sha_256_iterations
extern

Definition at line 194 of file auth-scram.c.

Referenced by pg_be_scram_build_secret().