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