PostgreSQL Source Code  git master
auth-scram.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * auth-scram.c
4  * Server-side implementation of the SASL SCRAM-SHA-256 mechanism.
5  *
6  * See the following RFCs for more details:
7  * - RFC 5802: https://tools.ietf.org/html/rfc5802
8  * - RFC 5803: https://tools.ietf.org/html/rfc5803
9  * - RFC 7677: https://tools.ietf.org/html/rfc7677
10  *
11  * Here are some differences:
12  *
13  * - Username from the authentication exchange is not used. The client
14  * should send an empty string as the username.
15  *
16  * - If the password isn't valid UTF-8, or contains characters prohibited
17  * by the SASLprep profile, we skip the SASLprep pre-processing and use
18  * the raw bytes in calculating the hash.
19  *
20  * - If channel binding is used, the channel binding type is always
21  * "tls-server-end-point". The spec says the default is "tls-unique"
22  * (RFC 5802, section 6.1. Default Channel Binding), but there are some
23  * problems with that. Firstly, not all SSL libraries provide an API to
24  * get the TLS Finished message, required to use "tls-unique". Secondly,
25  * "tls-unique" is not specified for TLS v1.3, and as of this writing,
26  * it's not clear if there will be a replacement. We could support both
27  * "tls-server-end-point" and "tls-unique", but for our use case,
28  * "tls-unique" doesn't really have any advantages. The main advantage
29  * of "tls-unique" would be that it works even if the server doesn't
30  * have a certificate, but PostgreSQL requires a server certificate
31  * whenever SSL is used, anyway.
32  *
33  *
34  * The password stored in pg_authid consists of the iteration count, salt,
35  * StoredKey and ServerKey.
36  *
37  * SASLprep usage
38  * --------------
39  *
40  * One notable difference to the SCRAM specification is that while the
41  * specification dictates that the password is in UTF-8, and prohibits
42  * certain characters, we are more lenient. If the password isn't a valid
43  * UTF-8 string, or contains prohibited characters, the raw bytes are used
44  * to calculate the hash instead, without SASLprep processing. This is
45  * because PostgreSQL supports other encodings too, and the encoding being
46  * used during authentication is undefined (client_encoding isn't set until
47  * after authentication). In effect, we try to interpret the password as
48  * UTF-8 and apply SASLprep processing, but if it looks invalid, we assume
49  * that it's in some other encoding.
50  *
51  * In the worst case, we misinterpret a password that's in a different
52  * encoding as being Unicode, because it happens to consists entirely of
53  * valid UTF-8 bytes, and we apply Unicode normalization to it. As long
54  * as we do that consistently, that will not lead to failed logins.
55  * Fortunately, the UTF-8 byte sequences that are ignored by SASLprep
56  * don't correspond to any commonly used characters in any of the other
57  * supported encodings, so it should not lead to any significant loss in
58  * entropy, even if the normalization is incorrectly applied to a
59  * non-UTF-8 password.
60  *
61  * Error handling
62  * --------------
63  *
64  * Don't reveal user information to an unauthenticated client. We don't
65  * want an attacker to be able to probe whether a particular username is
66  * valid. In SCRAM, the server has to read the salt and iteration count
67  * from the user's stored secret, and send it to the client. To avoid
68  * revealing whether a user exists, when the client tries to authenticate
69  * with a username that doesn't exist, or doesn't have a valid SCRAM
70  * secret in pg_authid, we create a fake salt and iteration count
71  * on-the-fly, and proceed with the authentication with that. In the end,
72  * we'll reject the attempt, as if an incorrect password was given. When
73  * we are performing a "mock" authentication, the 'doomed' flag in
74  * scram_state is set.
75  *
76  * In the error messages, avoid printing strings from the client, unless
77  * you check that they are pure ASCII. We don't want an unauthenticated
78  * attacker to be able to spam the logs with characters that are not valid
79  * to the encoding being used, whatever that is. We cannot avoid that in
80  * general, after logging in, but let's do what we can here.
81  *
82  *
83  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
84  * Portions Copyright (c) 1994, Regents of the University of California
85  *
86  * src/backend/libpq/auth-scram.c
87  *
88  *-------------------------------------------------------------------------
89  */
90 #include "postgres.h"
91 
92 #include <unistd.h>
93 
94 #include "access/xlog.h"
95 #include "catalog/pg_control.h"
96 #include "common/base64.h"
97 #include "common/hmac.h"
98 #include "common/saslprep.h"
99 #include "common/scram-common.h"
100 #include "common/sha2.h"
101 #include "libpq/crypt.h"
102 #include "libpq/sasl.h"
103 #include "libpq/scram.h"
104 
106 static void *scram_init(Port *port, const char *selected_mech,
107  const char *shadow_pass);
108 static int scram_exchange(void *opaq, const char *input, int inputlen,
109  char **output, int *outputlen,
110  const char **logdetail);
111 
112 /* Mechanism declaration */
115  scram_init,
117 };
118 
119 /*
120  * Status data for a SCRAM authentication exchange. This should be kept
121  * internal to this file.
122  */
123 typedef enum
124 {
129 
130 typedef struct
131 {
133 
134  const char *username; /* username from startup packet */
135 
138 
139  /* State data depending on the hash type */
142 
144  char *salt; /* base64-encoded */
147 
148  /* Fields of the first message from client */
153 
154  /* Fields from the last message from client */
157  char ClientProof[SCRAM_MAX_KEY_LEN];
158 
159  /* Fields generated in the server */
162 
163  /*
164  * If something goes wrong during the authentication, or we are performing
165  * a "mock" authentication (see comments at top of file), the 'doomed'
166  * flag is set. A reason for the failure, for the server log, is put in
167  * 'logdetail'.
168  */
169  bool doomed;
170  char *logdetail;
171 } scram_state;
172 
173 static void read_client_first_message(scram_state *state, const char *input);
174 static void read_client_final_message(scram_state *state, const char *input);
178 static bool verify_final_nonce(scram_state *state);
179 static void mock_scram_secret(const char *username, pg_cryptohash_type *hash_type,
180  int *iterations, int *key_length, char **salt,
181  uint8 *stored_key, uint8 *server_key);
182 static bool is_scram_printable(char *p);
183 static char *sanitize_char(char c);
184 static char *sanitize_str(const char *s);
185 static char *scram_mock_salt(const char *username,
186  pg_cryptohash_type hash_type,
187  int key_length);
188 
189 /*
190  * The number of iterations to use when generating new secrets.
191  */
193 
194 /*
195  * Get a list of SASL mechanisms that this module supports.
196  *
197  * For the convenience of building the FE/BE packet that lists the
198  * mechanisms, the names are appended to the given StringInfo buffer,
199  * separated by '\0' bytes.
200  */
201 static void
203 {
204  /*
205  * Advertise the mechanisms in decreasing order of importance. So the
206  * channel-binding variants go first, if they are supported. Channel
207  * binding is only supported with SSL.
208  */
209 #ifdef USE_SSL
210  if (port->ssl_in_use)
211  {
213  appendStringInfoChar(buf, '\0');
214  }
215 #endif
217  appendStringInfoChar(buf, '\0');
218 }
219 
220 /*
221  * Initialize a new SCRAM authentication exchange status tracker. This
222  * needs to be called before doing any exchange. It will be filled later
223  * after the beginning of the exchange with authentication information.
224  *
225  * 'selected_mech' identifies the SASL mechanism that the client selected.
226  * It should be one of the mechanisms that we support, as returned by
227  * scram_get_mechanisms().
228  *
229  * 'shadow_pass' is the role's stored secret, from pg_authid.rolpassword.
230  * The username was provided by the client in the startup message, and is
231  * available in port->user_name. If 'shadow_pass' is NULL, we still perform
232  * an authentication exchange, but it will fail, as if an incorrect password
233  * was given.
234  */
235 static void *
236 scram_init(Port *port, const char *selected_mech, const char *shadow_pass)
237 {
239  bool got_secret;
240 
241  state = (scram_state *) palloc0(sizeof(scram_state));
242  state->port = port;
243  state->state = SCRAM_AUTH_INIT;
244 
245  /*
246  * Parse the selected mechanism.
247  *
248  * Note that if we don't support channel binding, or if we're not using
249  * SSL at all, we would not have advertised the PLUS variant in the first
250  * place. If the client nevertheless tries to select it, it's a protocol
251  * violation like selecting any other SASL mechanism we don't support.
252  */
253 #ifdef USE_SSL
254  if (strcmp(selected_mech, SCRAM_SHA_256_PLUS_NAME) == 0 && port->ssl_in_use)
255  state->channel_binding_in_use = true;
256  else
257 #endif
258  if (strcmp(selected_mech, SCRAM_SHA_256_NAME) == 0)
259  state->channel_binding_in_use = false;
260  else
261  ereport(ERROR,
262  (errcode(ERRCODE_PROTOCOL_VIOLATION),
263  errmsg("client selected an invalid SASL authentication mechanism")));
264 
265  /*
266  * Parse the stored secret.
267  */
268  if (shadow_pass)
269  {
270  int password_type = get_password_type(shadow_pass);
271 
272  if (password_type == PASSWORD_TYPE_SCRAM_SHA_256)
273  {
274  if (parse_scram_secret(shadow_pass, &state->iterations,
275  &state->hash_type, &state->key_length,
276  &state->salt,
277  state->StoredKey,
278  state->ServerKey))
279  got_secret = true;
280  else
281  {
282  /*
283  * The password looked like a SCRAM secret, but could not be
284  * parsed.
285  */
286  ereport(LOG,
287  (errmsg("invalid SCRAM secret for user \"%s\"",
288  state->port->user_name)));
289  got_secret = false;
290  }
291  }
292  else
293  {
294  /*
295  * The user doesn't have SCRAM secret. (You cannot do SCRAM
296  * authentication with an MD5 hash.)
297  */
298  state->logdetail = psprintf(_("User \"%s\" does not have a valid SCRAM secret."),
299  state->port->user_name);
300  got_secret = false;
301  }
302  }
303  else
304  {
305  /*
306  * The caller requested us to perform a dummy authentication. This is
307  * considered normal, since the caller requested it, so don't set log
308  * detail.
309  */
310  got_secret = false;
311  }
312 
313  /*
314  * If the user did not have a valid SCRAM secret, we still go through the
315  * motions with a mock one, and fail as if the client supplied an
316  * incorrect password. This is to avoid revealing information to an
317  * attacker.
318  */
319  if (!got_secret)
320  {
321  mock_scram_secret(state->port->user_name, &state->hash_type,
322  &state->iterations, &state->key_length,
323  &state->salt,
324  state->StoredKey, state->ServerKey);
325  state->doomed = true;
326  }
327 
328  return state;
329 }
330 
331 /*
332  * Continue a SCRAM authentication exchange.
333  *
334  * 'input' is the SCRAM payload sent by the client. On the first call,
335  * 'input' contains the "Initial Client Response" that the client sent as
336  * part of the SASLInitialResponse message, or NULL if no Initial Client
337  * Response was given. (The SASL specification distinguishes between an
338  * empty response and non-existing one.) On subsequent calls, 'input'
339  * cannot be NULL. For convenience in this function, the caller must
340  * ensure that there is a null terminator at input[inputlen].
341  *
342  * The next message to send to client is saved in 'output', for a length
343  * of 'outputlen'. In the case of an error, optionally store a palloc'd
344  * string at *logdetail that will be sent to the postmaster log (but not
345  * the client).
346  */
347 static int
348 scram_exchange(void *opaq, const char *input, int inputlen,
349  char **output, int *outputlen, const char **logdetail)
350 {
351  scram_state *state = (scram_state *) opaq;
352  int result;
353 
354  *output = NULL;
355 
356  /*
357  * If the client didn't include an "Initial Client Response" in the
358  * SASLInitialResponse message, send an empty challenge, to which the
359  * client will respond with the same data that usually comes in the
360  * Initial Client Response.
361  */
362  if (input == NULL)
363  {
364  Assert(state->state == SCRAM_AUTH_INIT);
365 
366  *output = pstrdup("");
367  *outputlen = 0;
369  }
370 
371  /*
372  * Check that the input length agrees with the string length of the input.
373  * We can ignore inputlen after this.
374  */
375  if (inputlen == 0)
376  ereport(ERROR,
377  (errcode(ERRCODE_PROTOCOL_VIOLATION),
378  errmsg("malformed SCRAM message"),
379  errdetail("The message is empty.")));
380  if (inputlen != strlen(input))
381  ereport(ERROR,
382  (errcode(ERRCODE_PROTOCOL_VIOLATION),
383  errmsg("malformed SCRAM message"),
384  errdetail("Message length does not match input length.")));
385 
386  switch (state->state)
387  {
388  case SCRAM_AUTH_INIT:
389 
390  /*
391  * Initialization phase. Receive the first message from client
392  * and be sure that it parsed correctly. Then send the challenge
393  * to the client.
394  */
396 
397  /* prepare message to send challenge */
399 
400  state->state = SCRAM_AUTH_SALT_SENT;
401  result = PG_SASL_EXCHANGE_CONTINUE;
402  break;
403 
405 
406  /*
407  * Final phase for the server. Receive the response to the
408  * challenge previously sent, verify, and let the client know that
409  * everything went well (or not).
410  */
412 
414  ereport(ERROR,
415  (errcode(ERRCODE_PROTOCOL_VIOLATION),
416  errmsg("invalid SCRAM response"),
417  errdetail("Nonce does not match.")));
418 
419  /*
420  * Now check the final nonce and the client proof.
421  *
422  * If we performed a "mock" authentication that we knew would fail
423  * from the get go, this is where we fail.
424  *
425  * The SCRAM specification includes an error code,
426  * "invalid-proof", for authentication failure, but it also allows
427  * erroring out in an application-specific way. We choose to do
428  * the latter, so that the error message for invalid password is
429  * the same for all authentication methods. The caller will call
430  * ereport(), when we return PG_SASL_EXCHANGE_FAILURE with no
431  * output.
432  *
433  * NB: the order of these checks is intentional. We calculate the
434  * client proof even in a mock authentication, even though it's
435  * bound to fail, to thwart timing attacks to determine if a role
436  * with the given name exists or not.
437  */
438  if (!verify_client_proof(state) || state->doomed)
439  {
440  result = PG_SASL_EXCHANGE_FAILURE;
441  break;
442  }
443 
444  /* Build final message for client */
446 
447  /* Success! */
448  result = PG_SASL_EXCHANGE_SUCCESS;
449  state->state = SCRAM_AUTH_FINISHED;
450  break;
451 
452  default:
453  elog(ERROR, "invalid SCRAM exchange state");
454  result = PG_SASL_EXCHANGE_FAILURE;
455  }
456 
457  if (result == PG_SASL_EXCHANGE_FAILURE && state->logdetail && logdetail)
458  *logdetail = state->logdetail;
459 
460  if (*output)
461  *outputlen = strlen(*output);
462 
463  return result;
464 }
465 
466 /*
467  * Construct a SCRAM secret, for storing in pg_authid.rolpassword.
468  *
469  * The result is palloc'd, so caller is responsible for freeing it.
470  */
471 char *
473 {
474  char *prep_password;
475  pg_saslprep_rc rc;
476  char saltbuf[SCRAM_DEFAULT_SALT_LEN];
477  char *result;
478  const char *errstr = NULL;
479 
480  /*
481  * Normalize the password with SASLprep. If that doesn't work, because
482  * the password isn't valid UTF-8 or contains prohibited characters, just
483  * proceed with the original password. (See comments at top of file.)
484  */
485  rc = pg_saslprep(password, &prep_password);
486  if (rc == SASLPREP_SUCCESS)
487  password = (const char *) prep_password;
488 
489  /* Generate random salt */
491  ereport(ERROR,
492  (errcode(ERRCODE_INTERNAL_ERROR),
493  errmsg("could not generate random salt")));
494 
496  saltbuf, SCRAM_DEFAULT_SALT_LEN,
498  &errstr);
499 
500  if (prep_password)
501  pfree(prep_password);
502 
503  return result;
504 }
505 
506 /*
507  * Verify a plaintext password against a SCRAM secret. This is used when
508  * performing plaintext password authentication for a user that has a SCRAM
509  * secret stored in pg_authid.
510  */
511 bool
513  const char *secret)
514 {
515  char *encoded_salt;
516  char *salt;
517  int saltlen;
518  int iterations;
519  int key_length = 0;
520  pg_cryptohash_type hash_type;
521  uint8 salted_password[SCRAM_MAX_KEY_LEN];
522  uint8 stored_key[SCRAM_MAX_KEY_LEN];
523  uint8 server_key[SCRAM_MAX_KEY_LEN];
524  uint8 computed_key[SCRAM_MAX_KEY_LEN];
525  char *prep_password;
526  pg_saslprep_rc rc;
527  const char *errstr = NULL;
528 
529  if (!parse_scram_secret(secret, &iterations, &hash_type, &key_length,
530  &encoded_salt, stored_key, server_key))
531  {
532  /*
533  * The password looked like a SCRAM secret, but could not be parsed.
534  */
535  ereport(LOG,
536  (errmsg("invalid SCRAM secret for user \"%s\"", username)));
537  return false;
538  }
539 
540  saltlen = pg_b64_dec_len(strlen(encoded_salt));
541  salt = palloc(saltlen);
542  saltlen = pg_b64_decode(encoded_salt, strlen(encoded_salt), salt,
543  saltlen);
544  if (saltlen < 0)
545  {
546  ereport(LOG,
547  (errmsg("invalid SCRAM secret for user \"%s\"", username)));
548  return false;
549  }
550 
551  /* Normalize the password */
552  rc = pg_saslprep(password, &prep_password);
553  if (rc == SASLPREP_SUCCESS)
554  password = prep_password;
555 
556  /* Compute Server Key based on the user-supplied plaintext password */
557  if (scram_SaltedPassword(password, hash_type, key_length,
558  salt, saltlen, iterations,
559  salted_password, &errstr) < 0 ||
560  scram_ServerKey(salted_password, hash_type, key_length,
561  computed_key, &errstr) < 0)
562  {
563  elog(ERROR, "could not compute server key: %s", errstr);
564  }
565 
566  if (prep_password)
567  pfree(prep_password);
568 
569  /*
570  * Compare the secret's Server Key with the one computed from the
571  * user-supplied password.
572  */
573  return memcmp(computed_key, server_key, key_length) == 0;
574 }
575 
576 
577 /*
578  * Parse and validate format of given SCRAM secret.
579  *
580  * On success, the iteration count, salt, stored key, and server key are
581  * extracted from the secret, and returned to the caller. For 'stored_key'
582  * and 'server_key', the caller must pass pre-allocated buffers of size
583  * SCRAM_MAX_KEY_LEN. Salt is returned as a base64-encoded, null-terminated
584  * string. The buffer for the salt is palloc'd by this function.
585  *
586  * Returns true if the SCRAM secret has been parsed, and false otherwise.
587  */
588 bool
589 parse_scram_secret(const char *secret, int *iterations,
590  pg_cryptohash_type *hash_type, int *key_length,
591  char **salt, uint8 *stored_key, uint8 *server_key)
592 {
593  char *v;
594  char *p;
595  char *scheme_str;
596  char *salt_str;
597  char *iterations_str;
598  char *storedkey_str;
599  char *serverkey_str;
600  int decoded_len;
601  char *decoded_salt_buf;
602  char *decoded_stored_buf;
603  char *decoded_server_buf;
604 
605  /*
606  * The secret is of form:
607  *
608  * SCRAM-SHA-256$<iterations>:<salt>$<storedkey>:<serverkey>
609  */
610  v = pstrdup(secret);
611  if ((scheme_str = strsep(&v, "$")) == NULL)
612  goto invalid_secret;
613  if ((iterations_str = strsep(&v, ":")) == NULL)
614  goto invalid_secret;
615  if ((salt_str = strsep(&v, "$")) == NULL)
616  goto invalid_secret;
617  if ((storedkey_str = strsep(&v, ":")) == NULL)
618  goto invalid_secret;
619  serverkey_str = v;
620 
621  /* Parse the fields */
622  if (strcmp(scheme_str, "SCRAM-SHA-256") != 0)
623  goto invalid_secret;
624  *hash_type = PG_SHA256;
625  *key_length = SCRAM_SHA_256_KEY_LEN;
626 
627  errno = 0;
628  *iterations = strtol(iterations_str, &p, 10);
629  if (*p || errno != 0)
630  goto invalid_secret;
631 
632  /*
633  * Verify that the salt is in Base64-encoded format, by decoding it,
634  * although we return the encoded version to the caller.
635  */
636  decoded_len = pg_b64_dec_len(strlen(salt_str));
637  decoded_salt_buf = palloc(decoded_len);
638  decoded_len = pg_b64_decode(salt_str, strlen(salt_str),
639  decoded_salt_buf, decoded_len);
640  if (decoded_len < 0)
641  goto invalid_secret;
642  *salt = pstrdup(salt_str);
643 
644  /*
645  * Decode StoredKey and ServerKey.
646  */
647  decoded_len = pg_b64_dec_len(strlen(storedkey_str));
648  decoded_stored_buf = palloc(decoded_len);
649  decoded_len = pg_b64_decode(storedkey_str, strlen(storedkey_str),
650  decoded_stored_buf, decoded_len);
651  if (decoded_len != *key_length)
652  goto invalid_secret;
653  memcpy(stored_key, decoded_stored_buf, *key_length);
654 
655  decoded_len = pg_b64_dec_len(strlen(serverkey_str));
656  decoded_server_buf = palloc(decoded_len);
657  decoded_len = pg_b64_decode(serverkey_str, strlen(serverkey_str),
658  decoded_server_buf, decoded_len);
659  if (decoded_len != *key_length)
660  goto invalid_secret;
661  memcpy(server_key, decoded_server_buf, *key_length);
662 
663  return true;
664 
665 invalid_secret:
666  *salt = NULL;
667  return false;
668 }
669 
670 /*
671  * Generate plausible SCRAM secret parameters for mock authentication.
672  *
673  * In a normal authentication, these are extracted from the secret
674  * stored in the server. This function generates values that look
675  * realistic, for when there is no stored secret, using SCRAM-SHA-256.
676  *
677  * Like in parse_scram_secret(), for 'stored_key' and 'server_key', the
678  * caller must pass pre-allocated buffers of size SCRAM_MAX_KEY_LEN, and
679  * the buffer for the salt is palloc'd by this function.
680  */
681 static void
683  int *iterations, int *key_length, char **salt,
684  uint8 *stored_key, uint8 *server_key)
685 {
686  char *raw_salt;
687  char *encoded_salt;
688  int encoded_len;
689 
690  /* Enforce the use of SHA-256, which would be realistic enough */
691  *hash_type = PG_SHA256;
692  *key_length = SCRAM_SHA_256_KEY_LEN;
693 
694  /*
695  * Generate deterministic salt.
696  *
697  * Note that we cannot reveal any information to an attacker here so the
698  * error messages need to remain generic. This should never fail anyway
699  * as the salt generated for mock authentication uses the cluster's nonce
700  * value.
701  */
702  raw_salt = scram_mock_salt(username, *hash_type, *key_length);
703  if (raw_salt == NULL)
704  elog(ERROR, "could not encode salt");
705 
706  encoded_len = pg_b64_enc_len(SCRAM_DEFAULT_SALT_LEN);
707  /* don't forget the zero-terminator */
708  encoded_salt = (char *) palloc(encoded_len + 1);
709  encoded_len = pg_b64_encode(raw_salt, SCRAM_DEFAULT_SALT_LEN, encoded_salt,
710  encoded_len);
711 
712  if (encoded_len < 0)
713  elog(ERROR, "could not encode salt");
714  encoded_salt[encoded_len] = '\0';
715 
716  *salt = encoded_salt;
718 
719  /* StoredKey and ServerKey are not used in a doomed authentication */
720  memset(stored_key, 0, SCRAM_MAX_KEY_LEN);
721  memset(server_key, 0, SCRAM_MAX_KEY_LEN);
722 }
723 
724 /*
725  * Read the value in a given SCRAM exchange message for given attribute.
726  */
727 static char *
728 read_attr_value(char **input, char attr)
729 {
730  char *begin = *input;
731  char *end;
732 
733  if (*begin != attr)
734  ereport(ERROR,
735  (errcode(ERRCODE_PROTOCOL_VIOLATION),
736  errmsg("malformed SCRAM message"),
737  errdetail("Expected attribute \"%c\" but found \"%s\".",
738  attr, sanitize_char(*begin))));
739  begin++;
740 
741  if (*begin != '=')
742  ereport(ERROR,
743  (errcode(ERRCODE_PROTOCOL_VIOLATION),
744  errmsg("malformed SCRAM message"),
745  errdetail("Expected character \"=\" for attribute \"%c\".", attr)));
746  begin++;
747 
748  end = begin;
749  while (*end && *end != ',')
750  end++;
751 
752  if (*end)
753  {
754  *end = '\0';
755  *input = end + 1;
756  }
757  else
758  *input = end;
759 
760  return begin;
761 }
762 
763 static bool
765 {
766  /*------
767  * Printable characters, as defined by SCRAM spec: (RFC 5802)
768  *
769  * printable = %x21-2B / %x2D-7E
770  * ;; Printable ASCII except ",".
771  * ;; Note that any "printable" is also
772  * ;; a valid "value".
773  *------
774  */
775  for (; *p; p++)
776  {
777  if (*p < 0x21 || *p > 0x7E || *p == 0x2C /* comma */ )
778  return false;
779  }
780  return true;
781 }
782 
783 /*
784  * Convert an arbitrary byte to printable form. For error messages.
785  *
786  * If it's a printable ASCII character, print it as a single character.
787  * otherwise, print it in hex.
788  *
789  * The returned pointer points to a static buffer.
790  */
791 static char *
793 {
794  static char buf[5];
795 
796  if (c >= 0x21 && c <= 0x7E)
797  snprintf(buf, sizeof(buf), "'%c'", c);
798  else
799  snprintf(buf, sizeof(buf), "0x%02x", (unsigned char) c);
800  return buf;
801 }
802 
803 /*
804  * Convert an arbitrary string to printable form, for error messages.
805  *
806  * Anything that's not a printable ASCII character is replaced with
807  * '?', and the string is truncated at 30 characters.
808  *
809  * The returned pointer points to a static buffer.
810  */
811 static char *
812 sanitize_str(const char *s)
813 {
814  static char buf[30 + 1];
815  int i;
816 
817  for (i = 0; i < sizeof(buf) - 1; i++)
818  {
819  char c = s[i];
820 
821  if (c == '\0')
822  break;
823 
824  if (c >= 0x21 && c <= 0x7E)
825  buf[i] = c;
826  else
827  buf[i] = '?';
828  }
829  buf[i] = '\0';
830  return buf;
831 }
832 
833 /*
834  * Read the next attribute and value in a SCRAM exchange message.
835  *
836  * The attribute character is set in *attr_p, the attribute value is the
837  * return value.
838  */
839 static char *
840 read_any_attr(char **input, char *attr_p)
841 {
842  char *begin = *input;
843  char *end;
844  char attr = *begin;
845 
846  if (attr == '\0')
847  ereport(ERROR,
848  (errcode(ERRCODE_PROTOCOL_VIOLATION),
849  errmsg("malformed SCRAM message"),
850  errdetail("Attribute expected, but found end of string.")));
851 
852  /*------
853  * attr-val = ALPHA "=" value
854  * ;; Generic syntax of any attribute sent
855  * ;; by server or client
856  *------
857  */
858  if (!((attr >= 'A' && attr <= 'Z') ||
859  (attr >= 'a' && attr <= 'z')))
860  ereport(ERROR,
861  (errcode(ERRCODE_PROTOCOL_VIOLATION),
862  errmsg("malformed SCRAM message"),
863  errdetail("Attribute expected, but found invalid character \"%s\".",
864  sanitize_char(attr))));
865  if (attr_p)
866  *attr_p = attr;
867  begin++;
868 
869  if (*begin != '=')
870  ereport(ERROR,
871  (errcode(ERRCODE_PROTOCOL_VIOLATION),
872  errmsg("malformed SCRAM message"),
873  errdetail("Expected character \"=\" for attribute \"%c\".", attr)));
874  begin++;
875 
876  end = begin;
877  while (*end && *end != ',')
878  end++;
879 
880  if (*end)
881  {
882  *end = '\0';
883  *input = end + 1;
884  }
885  else
886  *input = end;
887 
888  return begin;
889 }
890 
891 /*
892  * Read and parse the first message from client in the context of a SCRAM
893  * authentication exchange message.
894  *
895  * At this stage, any errors will be reported directly with ereport(ERROR).
896  */
897 static void
899 {
900  char *p = pstrdup(input);
901  char *channel_binding_type;
902 
903 
904  /*------
905  * The syntax for the client-first-message is: (RFC 5802)
906  *
907  * saslname = 1*(value-safe-char / "=2C" / "=3D")
908  * ;; Conforms to <value>.
909  *
910  * authzid = "a=" saslname
911  * ;; Protocol specific.
912  *
913  * cb-name = 1*(ALPHA / DIGIT / "." / "-")
914  * ;; See RFC 5056, Section 7.
915  * ;; E.g., "tls-server-end-point" or
916  * ;; "tls-unique".
917  *
918  * gs2-cbind-flag = ("p=" cb-name) / "n" / "y"
919  * ;; "n" -> client doesn't support channel binding.
920  * ;; "y" -> client does support channel binding
921  * ;; but thinks the server does not.
922  * ;; "p" -> client requires channel binding.
923  * ;; The selected channel binding follows "p=".
924  *
925  * gs2-header = gs2-cbind-flag "," [ authzid ] ","
926  * ;; GS2 header for SCRAM
927  * ;; (the actual GS2 header includes an optional
928  * ;; flag to indicate that the GSS mechanism is not
929  * ;; "standard", but since SCRAM is "standard", we
930  * ;; don't include that flag).
931  *
932  * username = "n=" saslname
933  * ;; Usernames are prepared using SASLprep.
934  *
935  * reserved-mext = "m=" 1*(value-char)
936  * ;; Reserved for signaling mandatory extensions.
937  * ;; The exact syntax will be defined in
938  * ;; the future.
939  *
940  * nonce = "r=" c-nonce [s-nonce]
941  * ;; Second part provided by server.
942  *
943  * c-nonce = printable
944  *
945  * client-first-message-bare =
946  * [reserved-mext ","]
947  * username "," nonce ["," extensions]
948  *
949  * client-first-message =
950  * gs2-header client-first-message-bare
951  *
952  * For example:
953  * n,,n=user,r=fyko+d2lbbFgONRv9qkxdawL
954  *
955  * The "n,," in the beginning means that the client doesn't support
956  * channel binding, and no authzid is given. "n=user" is the username.
957  * However, in PostgreSQL the username is sent in the startup packet, and
958  * the username in the SCRAM exchange is ignored. libpq always sends it
959  * as an empty string. The last part, "r=fyko+d2lbbFgONRv9qkxdawL" is
960  * the client nonce.
961  *------
962  */
963 
964  /*
965  * Read gs2-cbind-flag. (For details see also RFC 5802 Section 6 "Channel
966  * Binding".)
967  */
968  state->cbind_flag = *p;
969  switch (*p)
970  {
971  case 'n':
972 
973  /*
974  * The client does not support channel binding or has simply
975  * decided to not use it. In that case just let it go.
976  */
977  if (state->channel_binding_in_use)
978  ereport(ERROR,
979  (errcode(ERRCODE_PROTOCOL_VIOLATION),
980  errmsg("malformed SCRAM message"),
981  errdetail("The client selected SCRAM-SHA-256-PLUS, but the SCRAM message does not include channel binding data.")));
982 
983  p++;
984  if (*p != ',')
985  ereport(ERROR,
986  (errcode(ERRCODE_PROTOCOL_VIOLATION),
987  errmsg("malformed SCRAM message"),
988  errdetail("Comma expected, but found character \"%s\".",
989  sanitize_char(*p))));
990  p++;
991  break;
992  case 'y':
993 
994  /*
995  * The client supports channel binding and thinks that the server
996  * does not. In this case, the server must fail authentication if
997  * it supports channel binding.
998  */
999  if (state->channel_binding_in_use)
1000  ereport(ERROR,
1001  (errcode(ERRCODE_PROTOCOL_VIOLATION),
1002  errmsg("malformed SCRAM message"),
1003  errdetail("The client selected SCRAM-SHA-256-PLUS, but the SCRAM message does not include channel binding data.")));
1004 
1005 #ifdef USE_SSL
1006  if (state->port->ssl_in_use)
1007  ereport(ERROR,
1008  (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
1009  errmsg("SCRAM channel binding negotiation error"),
1010  errdetail("The client supports SCRAM channel binding but thinks the server does not. "
1011  "However, this server does support channel binding.")));
1012 #endif
1013  p++;
1014  if (*p != ',')
1015  ereport(ERROR,
1016  (errcode(ERRCODE_PROTOCOL_VIOLATION),
1017  errmsg("malformed SCRAM message"),
1018  errdetail("Comma expected, but found character \"%s\".",
1019  sanitize_char(*p))));
1020  p++;
1021  break;
1022  case 'p':
1023 
1024  /*
1025  * The client requires channel binding. Channel binding type
1026  * follows, e.g., "p=tls-server-end-point".
1027  */
1028  if (!state->channel_binding_in_use)
1029  ereport(ERROR,
1030  (errcode(ERRCODE_PROTOCOL_VIOLATION),
1031  errmsg("malformed SCRAM message"),
1032  errdetail("The client selected SCRAM-SHA-256 without channel binding, but the SCRAM message includes channel binding data.")));
1033 
1034  channel_binding_type = read_attr_value(&p, 'p');
1035 
1036  /*
1037  * The only channel binding type we support is
1038  * tls-server-end-point.
1039  */
1040  if (strcmp(channel_binding_type, "tls-server-end-point") != 0)
1041  ereport(ERROR,
1042  (errcode(ERRCODE_PROTOCOL_VIOLATION),
1043  errmsg("unsupported SCRAM channel-binding type \"%s\"",
1044  sanitize_str(channel_binding_type))));
1045  break;
1046  default:
1047  ereport(ERROR,
1048  (errcode(ERRCODE_PROTOCOL_VIOLATION),
1049  errmsg("malformed SCRAM message"),
1050  errdetail("Unexpected channel-binding flag \"%s\".",
1051  sanitize_char(*p))));
1052  }
1053 
1054  /*
1055  * Forbid optional authzid (authorization identity). We don't support it.
1056  */
1057  if (*p == 'a')
1058  ereport(ERROR,
1059  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1060  errmsg("client uses authorization identity, but it is not supported")));
1061  if (*p != ',')
1062  ereport(ERROR,
1063  (errcode(ERRCODE_PROTOCOL_VIOLATION),
1064  errmsg("malformed SCRAM message"),
1065  errdetail("Unexpected attribute \"%s\" in client-first-message.",
1066  sanitize_char(*p))));
1067  p++;
1068 
1069  state->client_first_message_bare = pstrdup(p);
1070 
1071  /*
1072  * Any mandatory extensions would go here. We don't support any.
1073  *
1074  * RFC 5802 specifies error code "e=extensions-not-supported" for this,
1075  * but it can only be sent in the server-final message. We prefer to fail
1076  * immediately (which the RFC also allows).
1077  */
1078  if (*p == 'm')
1079  ereport(ERROR,
1080  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1081  errmsg("client requires an unsupported SCRAM extension")));
1082 
1083  /*
1084  * Read username. Note: this is ignored. We use the username from the
1085  * startup message instead, still it is kept around if provided as it
1086  * proves to be useful for debugging purposes.
1087  */
1088  state->client_username = read_attr_value(&p, 'n');
1089 
1090  /* read nonce and check that it is made of only printable characters */
1091  state->client_nonce = read_attr_value(&p, 'r');
1092  if (!is_scram_printable(state->client_nonce))
1093  ereport(ERROR,
1094  (errcode(ERRCODE_PROTOCOL_VIOLATION),
1095  errmsg("non-printable characters in SCRAM nonce")));
1096 
1097  /*
1098  * There can be any number of optional extensions after this. We don't
1099  * support any extensions, so ignore them.
1100  */
1101  while (*p != '\0')
1102  read_any_attr(&p, NULL);
1103 
1104  /* success! */
1105 }
1106 
1107 /*
1108  * Verify the final nonce contained in the last message received from
1109  * client in an exchange.
1110  */
1111 static bool
1113 {
1114  int client_nonce_len = strlen(state->client_nonce);
1115  int server_nonce_len = strlen(state->server_nonce);
1116  int final_nonce_len = strlen(state->client_final_nonce);
1117 
1118  if (final_nonce_len != client_nonce_len + server_nonce_len)
1119  return false;
1120  if (memcmp(state->client_final_nonce, state->client_nonce, client_nonce_len) != 0)
1121  return false;
1122  if (memcmp(state->client_final_nonce + client_nonce_len, state->server_nonce, server_nonce_len) != 0)
1123  return false;
1124 
1125  return true;
1126 }
1127 
1128 /*
1129  * Verify the client proof contained in the last message received from
1130  * client in an exchange. Returns true if the verification is a success,
1131  * or false for a failure.
1132  */
1133 static bool
1135 {
1136  uint8 ClientSignature[SCRAM_MAX_KEY_LEN];
1137  uint8 ClientKey[SCRAM_MAX_KEY_LEN];
1138  uint8 client_StoredKey[SCRAM_MAX_KEY_LEN];
1139  pg_hmac_ctx *ctx = pg_hmac_create(state->hash_type);
1140  int i;
1141  const char *errstr = NULL;
1142 
1143  /*
1144  * Calculate ClientSignature. Note that we don't log directly a failure
1145  * here even when processing the calculations as this could involve a mock
1146  * authentication.
1147  */
1148  if (pg_hmac_init(ctx, state->StoredKey, state->key_length) < 0 ||
1149  pg_hmac_update(ctx,
1150  (uint8 *) state->client_first_message_bare,
1151  strlen(state->client_first_message_bare)) < 0 ||
1152  pg_hmac_update(ctx, (uint8 *) ",", 1) < 0 ||
1153  pg_hmac_update(ctx,
1154  (uint8 *) state->server_first_message,
1155  strlen(state->server_first_message)) < 0 ||
1156  pg_hmac_update(ctx, (uint8 *) ",", 1) < 0 ||
1157  pg_hmac_update(ctx,
1158  (uint8 *) state->client_final_message_without_proof,
1159  strlen(state->client_final_message_without_proof)) < 0 ||
1160  pg_hmac_final(ctx, ClientSignature, state->key_length) < 0)
1161  {
1162  elog(ERROR, "could not calculate client signature: %s",
1163  pg_hmac_error(ctx));
1164  }
1165 
1166  pg_hmac_free(ctx);
1167 
1168  /* Extract the ClientKey that the client calculated from the proof */
1169  for (i = 0; i < state->key_length; i++)
1170  ClientKey[i] = state->ClientProof[i] ^ ClientSignature[i];
1171 
1172  /* Hash it one more time, and compare with StoredKey */
1173  if (scram_H(ClientKey, state->hash_type, state->key_length,
1174  client_StoredKey, &errstr) < 0)
1175  elog(ERROR, "could not hash stored key: %s", errstr);
1176 
1177  if (memcmp(client_StoredKey, state->StoredKey, state->key_length) != 0)
1178  return false;
1179 
1180  return true;
1181 }
1182 
1183 /*
1184  * Build the first server-side message sent to the client in a SCRAM
1185  * communication exchange.
1186  */
1187 static char *
1189 {
1190  /*------
1191  * The syntax for the server-first-message is: (RFC 5802)
1192  *
1193  * server-first-message =
1194  * [reserved-mext ","] nonce "," salt ","
1195  * iteration-count ["," extensions]
1196  *
1197  * nonce = "r=" c-nonce [s-nonce]
1198  * ;; Second part provided by server.
1199  *
1200  * c-nonce = printable
1201  *
1202  * s-nonce = printable
1203  *
1204  * salt = "s=" base64
1205  *
1206  * iteration-count = "i=" posit-number
1207  * ;; A positive number.
1208  *
1209  * Example:
1210  *
1211  * r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,s=QSXCR+Q6sek8bf92,i=4096
1212  *------
1213  */
1214 
1215  /*
1216  * Per the spec, the nonce may consist of any printable ASCII characters.
1217  * For convenience, however, we don't use the whole range available,
1218  * rather, we generate some random bytes, and base64 encode them.
1219  */
1220  char raw_nonce[SCRAM_RAW_NONCE_LEN];
1221  int encoded_len;
1222 
1223  if (!pg_strong_random(raw_nonce, SCRAM_RAW_NONCE_LEN))
1224  ereport(ERROR,
1225  (errcode(ERRCODE_INTERNAL_ERROR),
1226  errmsg("could not generate random nonce")));
1227 
1228  encoded_len = pg_b64_enc_len(SCRAM_RAW_NONCE_LEN);
1229  /* don't forget the zero-terminator */
1230  state->server_nonce = palloc(encoded_len + 1);
1231  encoded_len = pg_b64_encode(raw_nonce, SCRAM_RAW_NONCE_LEN,
1232  state->server_nonce, encoded_len);
1233  if (encoded_len < 0)
1234  ereport(ERROR,
1235  (errcode(ERRCODE_INTERNAL_ERROR),
1236  errmsg("could not encode random nonce")));
1237  state->server_nonce[encoded_len] = '\0';
1238 
1239  state->server_first_message =
1240  psprintf("r=%s%s,s=%s,i=%d",
1241  state->client_nonce, state->server_nonce,
1242  state->salt, state->iterations);
1243 
1244  return pstrdup(state->server_first_message);
1245 }
1246 
1247 
1248 /*
1249  * Read and parse the final message received from client.
1250  */
1251 static void
1253 {
1254  char attr;
1255  char *channel_binding;
1256  char *value;
1257  char *begin,
1258  *proof;
1259  char *p;
1260  char *client_proof;
1261  int client_proof_len;
1262 
1263  begin = p = pstrdup(input);
1264 
1265  /*------
1266  * The syntax for the server-first-message is: (RFC 5802)
1267  *
1268  * gs2-header = gs2-cbind-flag "," [ authzid ] ","
1269  * ;; GS2 header for SCRAM
1270  * ;; (the actual GS2 header includes an optional
1271  * ;; flag to indicate that the GSS mechanism is not
1272  * ;; "standard", but since SCRAM is "standard", we
1273  * ;; don't include that flag).
1274  *
1275  * cbind-input = gs2-header [ cbind-data ]
1276  * ;; cbind-data MUST be present for
1277  * ;; gs2-cbind-flag of "p" and MUST be absent
1278  * ;; for "y" or "n".
1279  *
1280  * channel-binding = "c=" base64
1281  * ;; base64 encoding of cbind-input.
1282  *
1283  * proof = "p=" base64
1284  *
1285  * client-final-message-without-proof =
1286  * channel-binding "," nonce [","
1287  * extensions]
1288  *
1289  * client-final-message =
1290  * client-final-message-without-proof "," proof
1291  *------
1292  */
1293 
1294  /*
1295  * Read channel binding. This repeats the channel-binding flags and is
1296  * then followed by the actual binding data depending on the type.
1297  */
1298  channel_binding = read_attr_value(&p, 'c');
1299  if (state->channel_binding_in_use)
1300  {
1301 #ifdef USE_SSL
1302  const char *cbind_data = NULL;
1303  size_t cbind_data_len = 0;
1304  size_t cbind_header_len;
1305  char *cbind_input;
1306  size_t cbind_input_len;
1307  char *b64_message;
1308  int b64_message_len;
1309 
1310  Assert(state->cbind_flag == 'p');
1311 
1312  /* Fetch hash data of server's SSL certificate */
1313  cbind_data = be_tls_get_certificate_hash(state->port,
1314  &cbind_data_len);
1315 
1316  /* should not happen */
1317  if (cbind_data == NULL || cbind_data_len == 0)
1318  elog(ERROR, "could not get server certificate hash");
1319 
1320  cbind_header_len = strlen("p=tls-server-end-point,,"); /* p=type,, */
1321  cbind_input_len = cbind_header_len + cbind_data_len;
1322  cbind_input = palloc(cbind_input_len);
1323  snprintf(cbind_input, cbind_input_len, "p=tls-server-end-point,,");
1324  memcpy(cbind_input + cbind_header_len, cbind_data, cbind_data_len);
1325 
1326  b64_message_len = pg_b64_enc_len(cbind_input_len);
1327  /* don't forget the zero-terminator */
1328  b64_message = palloc(b64_message_len + 1);
1329  b64_message_len = pg_b64_encode(cbind_input, cbind_input_len,
1330  b64_message, b64_message_len);
1331  if (b64_message_len < 0)
1332  elog(ERROR, "could not encode channel binding data");
1333  b64_message[b64_message_len] = '\0';
1334 
1335  /*
1336  * Compare the value sent by the client with the value expected by the
1337  * server.
1338  */
1339  if (strcmp(channel_binding, b64_message) != 0)
1340  ereport(ERROR,
1341  (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
1342  errmsg("SCRAM channel binding check failed")));
1343 #else
1344  /* shouldn't happen, because we checked this earlier already */
1345  elog(ERROR, "channel binding not supported by this build");
1346 #endif
1347  }
1348  else
1349  {
1350  /*
1351  * If we are not using channel binding, the binding data is expected
1352  * to always be "biws", which is "n,," base64-encoded, or "eSws",
1353  * which is "y,,". We also have to check whether the flag is the same
1354  * one that the client originally sent.
1355  */
1356  if (!(strcmp(channel_binding, "biws") == 0 && state->cbind_flag == 'n') &&
1357  !(strcmp(channel_binding, "eSws") == 0 && state->cbind_flag == 'y'))
1358  ereport(ERROR,
1359  (errcode(ERRCODE_PROTOCOL_VIOLATION),
1360  errmsg("unexpected SCRAM channel-binding attribute in client-final-message")));
1361  }
1362 
1363  state->client_final_nonce = read_attr_value(&p, 'r');
1364 
1365  /* ignore optional extensions, read until we find "p" attribute */
1366  do
1367  {
1368  proof = p - 1;
1369  value = read_any_attr(&p, &attr);
1370  } while (attr != 'p');
1371 
1372  client_proof_len = pg_b64_dec_len(strlen(value));
1373  client_proof = palloc(client_proof_len);
1374  if (pg_b64_decode(value, strlen(value), client_proof,
1375  client_proof_len) != state->key_length)
1376  ereport(ERROR,
1377  (errcode(ERRCODE_PROTOCOL_VIOLATION),
1378  errmsg("malformed SCRAM message"),
1379  errdetail("Malformed proof in client-final-message.")));
1380  memcpy(state->ClientProof, client_proof, state->key_length);
1381  pfree(client_proof);
1382 
1383  if (*p != '\0')
1384  ereport(ERROR,
1385  (errcode(ERRCODE_PROTOCOL_VIOLATION),
1386  errmsg("malformed SCRAM message"),
1387  errdetail("Garbage found at the end of client-final-message.")));
1388 
1389  state->client_final_message_without_proof = palloc(proof - begin + 1);
1390  memcpy(state->client_final_message_without_proof, input, proof - begin);
1391  state->client_final_message_without_proof[proof - begin] = '\0';
1392 }
1393 
1394 /*
1395  * Build the final server-side message of an exchange.
1396  */
1397 static char *
1399 {
1400  uint8 ServerSignature[SCRAM_MAX_KEY_LEN];
1401  char *server_signature_base64;
1402  int siglen;
1403  pg_hmac_ctx *ctx = pg_hmac_create(state->hash_type);
1404 
1405  /* calculate ServerSignature */
1406  if (pg_hmac_init(ctx, state->ServerKey, state->key_length) < 0 ||
1407  pg_hmac_update(ctx,
1408  (uint8 *) state->client_first_message_bare,
1409  strlen(state->client_first_message_bare)) < 0 ||
1410  pg_hmac_update(ctx, (uint8 *) ",", 1) < 0 ||
1411  pg_hmac_update(ctx,
1412  (uint8 *) state->server_first_message,
1413  strlen(state->server_first_message)) < 0 ||
1414  pg_hmac_update(ctx, (uint8 *) ",", 1) < 0 ||
1415  pg_hmac_update(ctx,
1416  (uint8 *) state->client_final_message_without_proof,
1417  strlen(state->client_final_message_without_proof)) < 0 ||
1418  pg_hmac_final(ctx, ServerSignature, state->key_length) < 0)
1419  {
1420  elog(ERROR, "could not calculate server signature: %s",
1421  pg_hmac_error(ctx));
1422  }
1423 
1424  pg_hmac_free(ctx);
1425 
1426  siglen = pg_b64_enc_len(state->key_length);
1427  /* don't forget the zero-terminator */
1428  server_signature_base64 = palloc(siglen + 1);
1429  siglen = pg_b64_encode((const char *) ServerSignature,
1430  state->key_length, server_signature_base64,
1431  siglen);
1432  if (siglen < 0)
1433  elog(ERROR, "could not encode server signature");
1434  server_signature_base64[siglen] = '\0';
1435 
1436  /*------
1437  * The syntax for the server-final-message is: (RFC 5802)
1438  *
1439  * verifier = "v=" base64
1440  * ;; base-64 encoded ServerSignature.
1441  *
1442  * server-final-message = (server-error / verifier)
1443  * ["," extensions]
1444  *
1445  *------
1446  */
1447  return psprintf("v=%s", server_signature_base64);
1448 }
1449 
1450 
1451 /*
1452  * Deterministically generate salt for mock authentication, using a SHA256
1453  * hash based on the username and a cluster-level secret key. Returns a
1454  * pointer to a static buffer of size SCRAM_DEFAULT_SALT_LEN, or NULL.
1455  */
1456 static char *
1458  int key_length)
1459 {
1460  pg_cryptohash_ctx *ctx;
1461  static uint8 sha_digest[SCRAM_MAX_KEY_LEN];
1462  char *mock_auth_nonce = GetMockAuthenticationNonce();
1463 
1464  /*
1465  * Generate salt using a SHA256 hash of the username and the cluster's
1466  * mock authentication nonce. (This works as long as the salt length is
1467  * not larger than the SHA256 digest length. If the salt is smaller, the
1468  * caller will just ignore the extra data.)
1469  */
1471  "salt length greater than SHA256 digest length");
1472 
1473  /*
1474  * This may be worth refreshing if support for more hash methods is\
1475  * added.
1476  */
1477  Assert(hash_type == PG_SHA256);
1478 
1479  ctx = pg_cryptohash_create(hash_type);
1480  if (pg_cryptohash_init(ctx) < 0 ||
1481  pg_cryptohash_update(ctx, (uint8 *) username, strlen(username)) < 0 ||
1482  pg_cryptohash_update(ctx, (uint8 *) mock_auth_nonce, MOCK_AUTH_NONCE_LEN) < 0 ||
1483  pg_cryptohash_final(ctx, sha_digest, key_length) < 0)
1484  {
1485  pg_cryptohash_free(ctx);
1486  return NULL;
1487  }
1488  pg_cryptohash_free(ctx);
1489 
1490  return (char *) sha_digest;
1491 }
static void * scram_init(Port *port, const char *selected_mech, const char *shadow_pass)
Definition: auth-scram.c:236
static char * build_server_first_message(scram_state *state)
Definition: auth-scram.c:1188
const pg_be_sasl_mech pg_be_scram_mech
Definition: auth-scram.c:113
static void read_client_first_message(scram_state *state, const char *input)
Definition: auth-scram.c:898
static char * read_attr_value(char **input, char attr)
Definition: auth-scram.c:728
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:589
static char * read_any_attr(char **input, char *attr_p)
Definition: auth-scram.c:840
static bool verify_client_proof(scram_state *state)
Definition: auth-scram.c:1134
static bool verify_final_nonce(scram_state *state)
Definition: auth-scram.c:1112
static char * sanitize_str(const char *s)
Definition: auth-scram.c:812
static char * scram_mock_salt(const char *username, pg_cryptohash_type hash_type, int key_length)
Definition: auth-scram.c:1457
static int scram_exchange(void *opaq, const char *input, int inputlen, char **output, int *outputlen, const char **logdetail)
Definition: auth-scram.c:348
static bool is_scram_printable(char *p)
Definition: auth-scram.c:764
static char * sanitize_char(char c)
Definition: auth-scram.c:792
char * pg_be_scram_build_secret(const char *password)
Definition: auth-scram.c:472
bool scram_verify_plain_password(const char *username, const char *password, const char *secret)
Definition: auth-scram.c:512
static void read_client_final_message(scram_state *state, const char *input)
Definition: auth-scram.c:1252
static void mock_scram_secret(const char *username, pg_cryptohash_type *hash_type, int *iterations, int *key_length, char **salt, uint8 *stored_key, uint8 *server_key)
Definition: auth-scram.c:682
static char * build_server_final_message(scram_state *state)
Definition: auth-scram.c:1398
static void scram_get_mechanisms(Port *port, StringInfo buf)
Definition: auth-scram.c:202
scram_state_enum
Definition: auth-scram.c:124
@ SCRAM_AUTH_SALT_SENT
Definition: auth-scram.c:126
@ SCRAM_AUTH_FINISHED
Definition: auth-scram.c:127
@ SCRAM_AUTH_INIT
Definition: auth-scram.c:125
int scram_sha_256_iterations
Definition: auth-scram.c:192
int pg_b64_decode(const char *src, int len, char *dst, int dstlen)
Definition: base64.c:116
int pg_b64_enc_len(int srclen)
Definition: base64.c:224
int pg_b64_encode(const char *src, int len, char *dst, int dstlen)
Definition: base64.c:49
int pg_b64_dec_len(int srclen)
Definition: base64.c:239
char * be_tls_get_certificate_hash(Port *port, size_t *len)
#define Assert(condition)
Definition: c.h:858
unsigned char uint8
Definition: c.h:504
#define StaticAssertDecl(condition, errmessage)
Definition: c.h:936
PasswordType get_password_type(const char *shadow_pass)
Definition: crypt.c:88
@ PASSWORD_TYPE_SCRAM_SHA_256
Definition: crypt.h:31
int pg_cryptohash_update(pg_cryptohash_ctx *ctx, const uint8 *data, size_t len)
Definition: cryptohash.c:136
int pg_cryptohash_init(pg_cryptohash_ctx *ctx)
Definition: cryptohash.c:100
void pg_cryptohash_free(pg_cryptohash_ctx *ctx)
Definition: cryptohash.c:238
pg_cryptohash_ctx * pg_cryptohash_create(pg_cryptohash_type type)
Definition: cryptohash.c:74
int pg_cryptohash_final(pg_cryptohash_ctx *ctx, uint8 *dest, size_t len)
Definition: cryptohash.c:172
pg_cryptohash_type
Definition: cryptohash.h:20
@ PG_SHA256
Definition: cryptohash.h:24
int errdetail(const char *fmt,...)
Definition: elog.c:1203
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define _(x)
Definition: elog.c:90
#define LOG
Definition: elog.h:31
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
#define ereport(elevel,...)
Definition: elog.h:149
pg_hmac_ctx * pg_hmac_create(pg_cryptohash_type type)
Definition: hmac.c:77
const char * pg_hmac_error(pg_hmac_ctx *ctx)
Definition: hmac.c:306
void pg_hmac_free(pg_hmac_ctx *ctx)
Definition: hmac.c:289
int pg_hmac_update(pg_hmac_ctx *ctx, const uint8 *data, size_t len)
Definition: hmac.c:223
int pg_hmac_init(pg_hmac_ctx *ctx, const uint8 *key, size_t len)
Definition: hmac.c:138
int pg_hmac_final(pg_hmac_ctx *ctx, uint8 *dest, size_t len)
Definition: hmac.c:244
FILE * input
FILE * output
static struct @155 value
static char * username
Definition: initdb.c:153
int i
Definition: isn.c:73
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
char * pstrdup(const char *in)
Definition: mcxt.c:1696
void pfree(void *pointer)
Definition: mcxt.c:1521
void * palloc0(Size size)
Definition: mcxt.c:1347
void * palloc(Size size)
Definition: mcxt.c:1317
#define MOCK_AUTH_NONCE_LEN
Definition: pg_control.h:28
static int port
Definition: pg_regress.c:116
static char * buf
Definition: pg_test_fsync.c:73
bool pg_strong_random(void *buf, size_t len)
char * strsep(char **stringp, const char *delim)
Definition: strsep.c:49
#define snprintf
Definition: port.h:238
char * c
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
#define PG_SASL_EXCHANGE_FAILURE
Definition: sasl.h:27
#define PG_SASL_EXCHANGE_CONTINUE
Definition: sasl.h:25
#define PG_SASL_EXCHANGE_SUCCESS
Definition: sasl.h:26
pg_saslprep_rc pg_saslprep(const char *input, char **output)
Definition: saslprep.c:1044
pg_saslprep_rc
Definition: saslprep.h:21
@ SASLPREP_SUCCESS
Definition: saslprep.h:22
int scram_ServerKey(const uint8 *salted_password, pg_cryptohash_type hash_type, int key_length, uint8 *result, const char **errstr)
Definition: scram-common.c:172
int scram_SaltedPassword(const char *password, pg_cryptohash_type hash_type, int key_length, const char *salt, int saltlen, int iterations, uint8 *result, const char **errstr)
Definition: scram-common.c:38
char * scram_build_secret(pg_cryptohash_type hash_type, int key_length, const char *salt, int saltlen, int iterations, const char *password, const char **errstr)
Definition: scram-common.c:210
int scram_H(const uint8 *input, pg_cryptohash_type hash_type, int key_length, uint8 *result, const char **errstr)
Definition: scram-common.c:112
#define SCRAM_SHA_256_PLUS_NAME
Definition: scram-common.h:21
#define SCRAM_SHA_256_NAME
Definition: scram-common.h:20
#define SCRAM_RAW_NONCE_LEN
Definition: scram-common.h:37
#define SCRAM_DEFAULT_SALT_LEN
Definition: scram-common.h:44
#define SCRAM_MAX_KEY_LEN
Definition: scram-common.h:30
#define SCRAM_SHA_256_KEY_LEN
Definition: scram-common.h:24
#define SCRAM_SHA_256_DEFAULT_ITERATIONS
Definition: scram-common.h:50
#define PG_SHA256_DIGEST_LENGTH
Definition: sha2.h:23
static char * password
Definition: streamutil.c:54
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:182
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:194
Definition: libpq-be.h:133
char * client_final_nonce
Definition: auth-scram.c:156
char * client_nonce
Definition: auth-scram.c:152
Port * port
Definition: auth-scram.c:136
char * salt
Definition: auth-scram.c:144
char * client_first_message_bare
Definition: auth-scram.c:150
char * logdetail
Definition: auth-scram.c:170
char * client_username
Definition: auth-scram.c:151
char * client_final_message_without_proof
Definition: auth-scram.c:155
scram_state_enum state
Definition: auth-scram.c:132
int key_length
Definition: auth-scram.c:141
char * server_first_message
Definition: auth-scram.c:160
char * server_nonce
Definition: auth-scram.c:161
bool channel_binding_in_use
Definition: auth-scram.c:137
char cbind_flag
Definition: auth-scram.c:149
int iterations
Definition: auth-scram.c:143
const char * username
Definition: auth-scram.c:134
pg_cryptohash_type hash_type
Definition: auth-scram.c:140
Definition: regguts.h:323
int iterations
Definition: thread-thread.c:39
char * GetMockAuthenticationNonce(void)
Definition: xlog.c:4543