Coverage Report

Created: 2026-08-14 06:37

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