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 * - Channel binding is not supported yet.
21 *
22 *
23 * The password stored in pg_authid consists of the iteration count, salt,
24 * StoredKey and ServerKey.
25 *
26 * SASLprep usage
27 * --------------
28 *
29 * One notable difference to the SCRAM specification is that while the
30 * specification dictates that the password is in UTF-8, and prohibits
31 * certain characters, we are more lenient. If the password isn't a valid
32 * UTF-8 string, or contains prohibited characters, the raw bytes are used
33 * to calculate the hash instead, without SASLprep processing. This is
34 * because PostgreSQL supports other encodings too, and the encoding being
35 * used during authentication is undefined (client_encoding isn't set until
36 * after authentication). In effect, we try to interpret the password as
37 * UTF-8 and apply SASLprep processing, but if it looks invalid, we assume
38 * that it's in some other encoding.
39 *
40 * In the worst case, we misinterpret a password that's in a different
41 * encoding as being Unicode, because it happens to consists entirely of
42 * valid UTF-8 bytes, and we apply Unicode normalization to it. As long
43 * as we do that consistently, that will not lead to failed logins.
44 * Fortunately, the UTF-8 byte sequences that are ignored by SASLprep
45 * don't correspond to any commonly used characters in any of the other
46 * supported encodings, so it should not lead to any significant loss in
47 * entropy, even if the normalization is incorrectly applied to a
48 * non-UTF-8 password.
49 *
50 * Error handling
51 * --------------
52 *
53 * Don't reveal user information to an unauthenticated client. We don't
54 * want an attacker to be able to probe whether a particular username is
55 * valid. In SCRAM, the server has to read the salt and iteration count
56 * from the user's password verifier, and send it to the client. To avoid
57 * revealing whether a user exists, when the client tries to authenticate
58 * with a username that doesn't exist, or doesn't have a valid SCRAM
59 * verifier in pg_authid, we create a fake salt and iteration count
60 * on-the-fly, and proceed with the authentication with that. In the end,
61 * we'll reject the attempt, as if an incorrect password was given. When
62 * we are performing a "mock" authentication, the 'doomed' flag in
63 * scram_state is set.
64 *
65 * In the error messages, avoid printing strings from the client, unless
66 * you check that they are pure ASCII. We don't want an unauthenticated
67 * attacker to be able to spam the logs with characters that are not valid
68 * to the encoding being used, whatever that is. We cannot avoid that in
69 * general, after logging in, but let's do what we can here.
70 *
71 *
72 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
73 * Portions Copyright (c) 1994, Regents of the University of California
74 *
75 * src/backend/libpq/auth-scram.c
76 *
77 *-------------------------------------------------------------------------
78 */
79 #include "postgres.h"
80
81 #include <unistd.h>
82
83 #include "access/xlog.h"
84 #include "catalog/pg_authid.h"
85 #include "catalog/pg_control.h"
86 #include "common/base64.h"
87 #include "common/saslprep.h"
88 #include "common/scram-common.h"
89 #include "common/sha2.h"
90 #include "libpq/auth.h"
91 #include "libpq/crypt.h"
92 #include "libpq/scram.h"
93 #include "miscadmin.h"
94 #include "utils/backend_random.h"
95 #include "utils/builtins.h"
96 #include "utils/timestamp.h"
97
98 /*
99 * Status data for a SCRAM authentication exchange. This should be kept
100 * internal to this file.
101 */
102 typedef enum
103 {
104 SCRAM_AUTH_INIT,
105 SCRAM_AUTH_SALT_SENT,
106 SCRAM_AUTH_FINISHED
107 } scram_state_enum;
108
109 typedef struct
110 {
111 scram_state_enum state;
112
113 const char *username; /* username from startup packet */
114
115 char cbind_flag;
116
117 int iterations;
118 char *salt; /* base64-encoded */
119 uint8 StoredKey[SCRAM_KEY_LEN];
120 uint8 ServerKey[SCRAM_KEY_LEN];
121
122 /* Fields of the first message from client */
123 char *client_first_message_bare;
124 char *client_username;
125 char *client_nonce;
126
127 /* Fields from the last message from client */
128 char *client_final_message_without_proof;
129 char *client_final_nonce;
130 char ClientProof[SCRAM_KEY_LEN];
131
132 /* Fields generated in the server */
133 char *server_first_message;
134 char *server_nonce;
135
136 /*
137 * If something goes wrong during the authentication, or we are performing
138 * a "mock" authentication (see comments at top of file), the 'doomed'
139 * flag is set. A reason for the failure, for the server log, is put in
140 * 'logdetail'.
141 */
142 bool doomed;
143 char *logdetail;
144 } scram_state;
145
146 static void read_client_first_message(scram_state *state, char *input);
147 static void read_client_final_message(scram_state *state, char *input);
148 static char *build_server_first_message(scram_state *state);
149 static char *build_server_final_message(scram_state *state);
150 static bool verify_client_proof(scram_state *state);
151 static bool verify_final_nonce(scram_state *state);
152 static void mock_scram_verifier(const char *username, int *iterations,
153 char **salt, uint8 *stored_key, uint8 *server_key);
154 static bool is_scram_printable(char *p);
155 static char *sanitize_char(char c);
156 static char *scram_mock_salt(const char *username);
157
158 /*
159 * pg_be_scram_init
160 *
161 * Initialize a new SCRAM authentication exchange status tracker. This
162 * needs to be called before doing any exchange. It will be filled later
163 * after the beginning of the exchange with verifier data.
164 *
165 * 'username' is the username provided by the client in the startup message.
166 * 'shadow_pass' is the role's password verifier, from pg_authid.rolpassword.
167 * If 'shadow_pass' is NULL, we still perform an authentication exchange, but
168 * it will fail, as if an incorrect password was given.
169 */
170 void *
pg_be_scram_init(const char * username,const char * shadow_pass)171 pg_be_scram_init(const char *username, const char *shadow_pass)
172 {
173 scram_state *state;
174 bool got_verifier;
175
176 state = (scram_state *) palloc0(sizeof(scram_state));
177 state->state = SCRAM_AUTH_INIT;
178 state->username = username;
179
180 /*
181 * Parse the stored password verifier.
182 */
183 if (shadow_pass)
184 {
185 int password_type = get_password_type(shadow_pass);
186
187 if (password_type == PASSWORD_TYPE_SCRAM_SHA_256)
188 {
189 if (parse_scram_verifier(shadow_pass, &state->iterations, &state->salt,
190 state->StoredKey, state->ServerKey))
191 got_verifier = true;
192 else
193 {
194 /*
195 * The password looked like a SCRAM verifier, but could not be
196 * parsed.
197 */
198 ereport(LOG,
199 (errmsg("invalid SCRAM verifier for user \"%s\"",
200 username)));
201 got_verifier = false;
202 }
203 }
204 else
205 {
206 /*
207 * The user doesn't have SCRAM verifier. (You cannot do SCRAM
208 * authentication with an MD5 hash.)
209 */
210 state->logdetail = psprintf(_("User \"%s\" does not have a valid SCRAM verifier."),
211 state->username);
212 got_verifier = false;
213 }
214 }
215 else
216 {
217 /*
218 * The caller requested us to perform a dummy authentication. This is
219 * considered normal, since the caller requested it, so don't set log
220 * detail.
221 */
222 got_verifier = false;
223 }
224
225 /*
226 * If the user did not have a valid SCRAM verifier, we still go through
227 * the motions with a mock one, and fail as if the client supplied an
228 * incorrect password. This is to avoid revealing information to an
229 * attacker.
230 */
231 if (!got_verifier)
232 {
233 mock_scram_verifier(username, &state->iterations, &state->salt,
234 state->StoredKey, state->ServerKey);
235 state->doomed = true;
236 }
237
238 return state;
239 }
240
241 /*
242 * Continue a SCRAM authentication exchange.
243 *
244 * 'input' is the SCRAM payload sent by the client. On the first call,
245 * 'input' contains the "Initial Client Response" that the client sent as
246 * part of the SASLInitialResponse message, or NULL if no Initial Client
247 * Response was given. (The SASL specification distinguishes between an
248 * empty response and non-existing one.) On subsequent calls, 'input'
249 * cannot be NULL. For convenience in this function, the caller must
250 * ensure that there is a null terminator at input[inputlen].
251 *
252 * The next message to send to client is saved in 'output', for a length
253 * of 'outputlen'. In the case of an error, optionally store a palloc'd
254 * string at *logdetail that will be sent to the postmaster log (but not
255 * the client).
256 */
257 int
pg_be_scram_exchange(void * opaq,char * input,int inputlen,char ** output,int * outputlen,char ** logdetail)258 pg_be_scram_exchange(void *opaq, char *input, int inputlen,
259 char **output, int *outputlen, char **logdetail)
260 {
261 scram_state *state = (scram_state *) opaq;
262 int result;
263
264 *output = NULL;
265
266 /*
267 * If the client didn't include an "Initial Client Response" in the
268 * SASLInitialResponse message, send an empty challenge, to which the
269 * client will respond with the same data that usually comes in the
270 * Initial Client Response.
271 */
272 if (input == NULL)
273 {
274 Assert(state->state == SCRAM_AUTH_INIT);
275
276 *output = pstrdup("");
277 *outputlen = 0;
278 return SASL_EXCHANGE_CONTINUE;
279 }
280
281 /*
282 * Check that the input length agrees with the string length of the input.
283 * We can ignore inputlen after this.
284 */
285 if (inputlen == 0)
286 ereport(ERROR,
287 (errcode(ERRCODE_PROTOCOL_VIOLATION),
288 errmsg("malformed SCRAM message"),
289 errdetail("The message is empty.")));
290 if (inputlen != strlen(input))
291 ereport(ERROR,
292 (errcode(ERRCODE_PROTOCOL_VIOLATION),
293 errmsg("malformed SCRAM message"),
294 errdetail("Message length does not match input length.")));
295
296 switch (state->state)
297 {
298 case SCRAM_AUTH_INIT:
299
300 /*
301 * Initialization phase. Receive the first message from client
302 * and be sure that it parsed correctly. Then send the challenge
303 * to the client.
304 */
305 read_client_first_message(state, input);
306
307 /* prepare message to send challenge */
308 *output = build_server_first_message(state);
309
310 state->state = SCRAM_AUTH_SALT_SENT;
311 result = SASL_EXCHANGE_CONTINUE;
312 break;
313
314 case SCRAM_AUTH_SALT_SENT:
315
316 /*
317 * Final phase for the server. Receive the response to the
318 * challenge previously sent, verify, and let the client know that
319 * everything went well (or not).
320 */
321 read_client_final_message(state, input);
322
323 if (!verify_final_nonce(state))
324 ereport(ERROR,
325 (errcode(ERRCODE_PROTOCOL_VIOLATION),
326 errmsg("invalid SCRAM response"),
327 errdetail("Nonce does not match.")));
328
329 /*
330 * Now check the final nonce and the client proof.
331 *
332 * If we performed a "mock" authentication that we knew would fail
333 * from the get go, this is where we fail.
334 *
335 * The SCRAM specification includes an error code,
336 * "invalid-proof", for authentication failure, but it also allows
337 * erroring out in an application-specific way. We choose to do
338 * the latter, so that the error message for invalid password is
339 * the same for all authentication methods. The caller will call
340 * ereport(), when we return SASL_EXCHANGE_FAILURE with no output.
341 *
342 * NB: the order of these checks is intentional. We calculate the
343 * client proof even in a mock authentication, even though it's
344 * bound to fail, to thwart timing attacks to determine if a role
345 * with the given name exists or not.
346 */
347 if (!verify_client_proof(state) || state->doomed)
348 {
349 result = SASL_EXCHANGE_FAILURE;
350 break;
351 }
352
353 /* Build final message for client */
354 *output = build_server_final_message(state);
355
356 /* Success! */
357 result = SASL_EXCHANGE_SUCCESS;
358 state->state = SCRAM_AUTH_FINISHED;
359 break;
360
361 default:
362 elog(ERROR, "invalid SCRAM exchange state");
363 result = SASL_EXCHANGE_FAILURE;
364 }
365
366 if (result == SASL_EXCHANGE_FAILURE && state->logdetail && logdetail)
367 *logdetail = state->logdetail;
368
369 if (*output)
370 *outputlen = strlen(*output);
371
372 return result;
373 }
374
375 /*
376 * Construct a verifier string for SCRAM, stored in pg_authid.rolpassword.
377 *
378 * The result is palloc'd, so caller is responsible for freeing it.
379 */
380 char *
pg_be_scram_build_verifier(const char * password)381 pg_be_scram_build_verifier(const char *password)
382 {
383 char *prep_password;
384 pg_saslprep_rc rc;
385 char saltbuf[SCRAM_DEFAULT_SALT_LEN];
386 char *result;
387
388 /*
389 * Normalize the password with SASLprep. If that doesn't work, because
390 * the password isn't valid UTF-8 or contains prohibited characters, just
391 * proceed with the original password. (See comments at top of file.)
392 */
393 rc = pg_saslprep(password, &prep_password);
394 if (rc == SASLPREP_SUCCESS)
395 password = (const char *) prep_password;
396
397 /* Generate random salt */
398 if (!pg_backend_random(saltbuf, SCRAM_DEFAULT_SALT_LEN))
399 ereport(ERROR,
400 (errcode(ERRCODE_INTERNAL_ERROR),
401 errmsg("could not generate random salt")));
402
403 result = scram_build_verifier(saltbuf, SCRAM_DEFAULT_SALT_LEN,
404 SCRAM_DEFAULT_ITERATIONS, password);
405
406 if (prep_password)
407 pfree(prep_password);
408
409 return result;
410 }
411
412 /*
413 * Verify a plaintext password against a SCRAM verifier. This is used when
414 * performing plaintext password authentication for a user that has a SCRAM
415 * verifier stored in pg_authid.
416 */
417 bool
scram_verify_plain_password(const char * username,const char * password,const char * verifier)418 scram_verify_plain_password(const char *username, const char *password,
419 const char *verifier)
420 {
421 char *encoded_salt;
422 char *salt;
423 int saltlen;
424 int iterations;
425 uint8 salted_password[SCRAM_KEY_LEN];
426 uint8 stored_key[SCRAM_KEY_LEN];
427 uint8 server_key[SCRAM_KEY_LEN];
428 uint8 computed_key[SCRAM_KEY_LEN];
429 char *prep_password;
430 pg_saslprep_rc rc;
431
432 if (!parse_scram_verifier(verifier, &iterations, &encoded_salt,
433 stored_key, server_key))
434 {
435 /*
436 * The password looked like a SCRAM verifier, but could not be parsed.
437 */
438 ereport(LOG,
439 (errmsg("invalid SCRAM verifier for user \"%s\"", username)));
440 return false;
441 }
442
443 salt = palloc(pg_b64_dec_len(strlen(encoded_salt)));
444 saltlen = pg_b64_decode(encoded_salt, strlen(encoded_salt), salt);
445 if (saltlen == -1)
446 {
447 ereport(LOG,
448 (errmsg("invalid SCRAM verifier for user \"%s\"", username)));
449 return false;
450 }
451
452 /* Normalize the password */
453 rc = pg_saslprep(password, &prep_password);
454 if (rc == SASLPREP_SUCCESS)
455 password = prep_password;
456
457 /* Compute Server Key based on the user-supplied plaintext password */
458 scram_SaltedPassword(password, salt, saltlen, iterations, salted_password);
459 scram_ServerKey(salted_password, computed_key);
460
461 if (prep_password)
462 pfree(prep_password);
463
464 /*
465 * Compare the verifier's Server Key with the one computed from the
466 * user-supplied password.
467 */
468 return memcmp(computed_key, server_key, SCRAM_KEY_LEN) == 0;
469 }
470
471
472 /*
473 * Parse and validate format of given SCRAM verifier.
474 *
475 * On success, the iteration count, salt, stored key, and server key are
476 * extracted from the verifier, and returned to the caller. For 'stored_key'
477 * and 'server_key', the caller must pass pre-allocated buffers of size
478 * SCRAM_KEY_LEN. Salt is returned as a base64-encoded, null-terminated
479 * string. The buffer for the salt is palloc'd by this function.
480 *
481 * Returns true if the SCRAM verifier has been parsed, and false otherwise.
482 */
483 bool
parse_scram_verifier(const char * verifier,int * iterations,char ** salt,uint8 * stored_key,uint8 * server_key)484 parse_scram_verifier(const char *verifier, int *iterations, char **salt,
485 uint8 *stored_key, uint8 *server_key)
486 {
487 char *v;
488 char *p;
489 char *scheme_str;
490 char *salt_str;
491 char *iterations_str;
492 char *storedkey_str;
493 char *serverkey_str;
494 int decoded_len;
495 char *decoded_salt_buf;
496 char *decoded_stored_buf;
497 char *decoded_server_buf;
498
499 /*
500 * The verifier is of form:
501 *
502 * SCRAM-SHA-256$<iterations>:<salt>$<storedkey>:<serverkey>
503 */
504 v = pstrdup(verifier);
505 if ((scheme_str = strtok(v, "$")) == NULL)
506 goto invalid_verifier;
507 if ((iterations_str = strtok(NULL, ":")) == NULL)
508 goto invalid_verifier;
509 if ((salt_str = strtok(NULL, "$")) == NULL)
510 goto invalid_verifier;
511 if ((storedkey_str = strtok(NULL, ":")) == NULL)
512 goto invalid_verifier;
513 if ((serverkey_str = strtok(NULL, "")) == NULL)
514 goto invalid_verifier;
515
516 /* Parse the fields */
517 if (strcmp(scheme_str, "SCRAM-SHA-256") != 0)
518 goto invalid_verifier;
519
520 errno = 0;
521 *iterations = strtol(iterations_str, &p, 10);
522 if (*p || errno != 0)
523 goto invalid_verifier;
524
525 /*
526 * Verify that the salt is in Base64-encoded format, by decoding it,
527 * although we return the encoded version to the caller.
528 */
529 decoded_salt_buf = palloc(pg_b64_dec_len(strlen(salt_str)));
530 decoded_len = pg_b64_decode(salt_str, strlen(salt_str),
531 decoded_salt_buf);
532 if (decoded_len < 0)
533 goto invalid_verifier;
534 *salt = pstrdup(salt_str);
535
536 /*
537 * Decode StoredKey and ServerKey.
538 */
539 decoded_stored_buf = palloc(pg_b64_dec_len(strlen(storedkey_str)));
540 decoded_len = pg_b64_decode(storedkey_str, strlen(storedkey_str),
541 decoded_stored_buf);
542 if (decoded_len != SCRAM_KEY_LEN)
543 goto invalid_verifier;
544 memcpy(stored_key, decoded_stored_buf, SCRAM_KEY_LEN);
545
546 decoded_server_buf = palloc(pg_b64_dec_len(strlen(serverkey_str)));
547 decoded_len = pg_b64_decode(serverkey_str, strlen(serverkey_str),
548 decoded_server_buf);
549 if (decoded_len != SCRAM_KEY_LEN)
550 goto invalid_verifier;
551 memcpy(server_key, decoded_server_buf, SCRAM_KEY_LEN);
552
553 return true;
554
555 invalid_verifier:
556 *salt = NULL;
557 return false;
558 }
559
560 /*
561 * Generate plausible SCRAM verifier parameters for mock authentication.
562 *
563 * In a normal authentication, these are extracted from the verifier
564 * stored in the server. This function generates values that look
565 * realistic, for when there is no stored verifier.
566 *
567 * Like in parse_scram_verifier(), for 'stored_key' and 'server_key', the
568 * caller must pass pre-allocated buffers of size SCRAM_KEY_LEN, and
569 * the buffer for the salt is palloc'd by this function.
570 */
571 static void
mock_scram_verifier(const char * username,int * iterations,char ** salt,uint8 * stored_key,uint8 * server_key)572 mock_scram_verifier(const char *username, int *iterations, char **salt,
573 uint8 *stored_key, uint8 *server_key)
574 {
575 char *raw_salt;
576 char *encoded_salt;
577 int encoded_len;
578
579 /* Generate deterministic salt */
580 raw_salt = scram_mock_salt(username);
581
582 encoded_salt = (char *) palloc(pg_b64_enc_len(SCRAM_DEFAULT_SALT_LEN) + 1);
583 encoded_len = pg_b64_encode(raw_salt, SCRAM_DEFAULT_SALT_LEN, encoded_salt);
584 encoded_salt[encoded_len] = '\0';
585
586 *salt = encoded_salt;
587 *iterations = SCRAM_DEFAULT_ITERATIONS;
588
589 /* StoredKey and ServerKey are not used in a doomed authentication */
590 memset(stored_key, 0, SCRAM_KEY_LEN);
591 memset(server_key, 0, SCRAM_KEY_LEN);
592 }
593
594 /*
595 * Read the value in a given SCRAM exchange message for given attribute.
596 */
597 static char *
read_attr_value(char ** input,char attr)598 read_attr_value(char **input, char attr)
599 {
600 char *begin = *input;
601 char *end;
602
603 if (*begin != attr)
604 ereport(ERROR,
605 (errcode(ERRCODE_PROTOCOL_VIOLATION),
606 errmsg("malformed SCRAM message"),
607 errdetail("Expected attribute \"%c\" but found \"%s\".",
608 attr, sanitize_char(*begin))));
609 begin++;
610
611 if (*begin != '=')
612 ereport(ERROR,
613 (errcode(ERRCODE_PROTOCOL_VIOLATION),
614 errmsg("malformed SCRAM message"),
615 errdetail("Expected character \"=\" for attribute \"%c\".", attr)));
616 begin++;
617
618 end = begin;
619 while (*end && *end != ',')
620 end++;
621
622 if (*end)
623 {
624 *end = '\0';
625 *input = end + 1;
626 }
627 else
628 *input = end;
629
630 return begin;
631 }
632
633 static bool
is_scram_printable(char * p)634 is_scram_printable(char *p)
635 {
636 /*------
637 * Printable characters, as defined by SCRAM spec: (RFC 5802)
638 *
639 * printable = %x21-2B / %x2D-7E
640 * ;; Printable ASCII except ",".
641 * ;; Note that any "printable" is also
642 * ;; a valid "value".
643 *------
644 */
645 for (; *p; p++)
646 {
647 if (*p < 0x21 || *p > 0x7E || *p == 0x2C /* comma */ )
648 return false;
649 }
650 return true;
651 }
652
653 /*
654 * Convert an arbitrary byte to printable form. For error messages.
655 *
656 * If it's a printable ASCII character, print it as a single character.
657 * otherwise, print it in hex.
658 *
659 * The returned pointer points to a static buffer.
660 */
661 static char *
sanitize_char(char c)662 sanitize_char(char c)
663 {
664 static char buf[5];
665
666 if (c >= 0x21 && c <= 0x7E)
667 snprintf(buf, sizeof(buf), "'%c'", c);
668 else
669 snprintf(buf, sizeof(buf), "0x%02x", (unsigned char) c);
670 return buf;
671 }
672
673 /*
674 * Read the next attribute and value in a SCRAM exchange message.
675 *
676 * Returns NULL if there is attribute.
677 */
678 static char *
read_any_attr(char ** input,char * attr_p)679 read_any_attr(char **input, char *attr_p)
680 {
681 char *begin = *input;
682 char *end;
683 char attr = *begin;
684
685 /*------
686 * attr-val = ALPHA "=" value
687 * ;; Generic syntax of any attribute sent
688 * ;; by server or client
689 *------
690 */
691 if (!((attr >= 'A' && attr <= 'Z') ||
692 (attr >= 'a' && attr <= 'z')))
693 ereport(ERROR,
694 (errcode(ERRCODE_PROTOCOL_VIOLATION),
695 errmsg("malformed SCRAM message"),
696 errdetail("Attribute expected, but found invalid character \"%s\".",
697 sanitize_char(attr))));
698 if (attr_p)
699 *attr_p = attr;
700 begin++;
701
702 if (*begin != '=')
703 ereport(ERROR,
704 (errcode(ERRCODE_PROTOCOL_VIOLATION),
705 errmsg("malformed SCRAM message"),
706 errdetail("Expected character \"=\" for attribute \"%c\".", attr)));
707 begin++;
708
709 end = begin;
710 while (*end && *end != ',')
711 end++;
712
713 if (*end)
714 {
715 *end = '\0';
716 *input = end + 1;
717 }
718 else
719 *input = end;
720
721 return begin;
722 }
723
724 /*
725 * Read and parse the first message from client in the context of a SCRAM
726 * authentication exchange message.
727 *
728 * At this stage, any errors will be reported directly with ereport(ERROR).
729 */
730 static void
read_client_first_message(scram_state * state,char * input)731 read_client_first_message(scram_state *state, char *input)
732 {
733 input = pstrdup(input);
734
735 /*------
736 * The syntax for the client-first-message is: (RFC 5802)
737 *
738 * saslname = 1*(value-safe-char / "=2C" / "=3D")
739 * ;; Conforms to <value>.
740 *
741 * authzid = "a=" saslname
742 * ;; Protocol specific.
743 *
744 * cb-name = 1*(ALPHA / DIGIT / "." / "-")
745 * ;; See RFC 5056, Section 7.
746 * ;; E.g., "tls-server-end-point" or
747 * ;; "tls-unique".
748 *
749 * gs2-cbind-flag = ("p=" cb-name) / "n" / "y"
750 * ;; "n" -> client doesn't support channel binding.
751 * ;; "y" -> client does support channel binding
752 * ;; but thinks the server does not.
753 * ;; "p" -> client requires channel binding.
754 * ;; The selected channel binding follows "p=".
755 *
756 * gs2-header = gs2-cbind-flag "," [ authzid ] ","
757 * ;; GS2 header for SCRAM
758 * ;; (the actual GS2 header includes an optional
759 * ;; flag to indicate that the GSS mechanism is not
760 * ;; "standard", but since SCRAM is "standard", we
761 * ;; don't include that flag).
762 *
763 * username = "n=" saslname
764 * ;; Usernames are prepared using SASLprep.
765 *
766 * reserved-mext = "m=" 1*(value-char)
767 * ;; Reserved for signaling mandatory extensions.
768 * ;; The exact syntax will be defined in
769 * ;; the future.
770 *
771 * nonce = "r=" c-nonce [s-nonce]
772 * ;; Second part provided by server.
773 *
774 * c-nonce = printable
775 *
776 * client-first-message-bare =
777 * [reserved-mext ","]
778 * username "," nonce ["," extensions]
779 *
780 * client-first-message =
781 * gs2-header client-first-message-bare
782 *
783 * For example:
784 * n,,n=user,r=fyko+d2lbbFgONRv9qkxdawL
785 *
786 * The "n,," in the beginning means that the client doesn't support
787 * channel binding, and no authzid is given. "n=user" is the username.
788 * However, in PostgreSQL the username is sent in the startup packet, and
789 * the username in the SCRAM exchange is ignored. libpq always sends it
790 * as an empty string. The last part, "r=fyko+d2lbbFgONRv9qkxdawL" is
791 * the client nonce.
792 *------
793 */
794
795 /* read gs2-cbind-flag */
796 state->cbind_flag = *input;
797 switch (*input)
798 {
799 case 'n':
800 /* Client does not support channel binding */
801 input++;
802 break;
803 case 'y':
804 /* Client supports channel binding, but we're not doing it today */
805 input++;
806 break;
807 case 'p':
808
809 /*
810 * Client requires channel binding. We don't support it.
811 *
812 * RFC 5802 specifies a particular error code,
813 * e=server-does-support-channel-binding, for this. But it can
814 * only be sent in the server-final message, and we don't want to
815 * go through the motions of the authentication, knowing it will
816 * fail, just to send that error message.
817 */
818 ereport(ERROR,
819 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
820 errmsg("client requires SCRAM channel binding, but it is not supported")));
821 default:
822 ereport(ERROR,
823 (errcode(ERRCODE_PROTOCOL_VIOLATION),
824 errmsg("malformed SCRAM message"),
825 errdetail("Unexpected channel-binding flag \"%s\".",
826 sanitize_char(*input))));
827 }
828 if (*input != ',')
829 ereport(ERROR,
830 (errcode(ERRCODE_PROTOCOL_VIOLATION),
831 errmsg("malformed SCRAM message"),
832 errdetail("Comma expected, but found character \"%s\".",
833 sanitize_char(*input))));
834 input++;
835
836 /*
837 * Forbid optional authzid (authorization identity). We don't support it.
838 */
839 if (*input == 'a')
840 ereport(ERROR,
841 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
842 errmsg("client uses authorization identity, but it is not supported")));
843 if (*input != ',')
844 ereport(ERROR,
845 (errcode(ERRCODE_PROTOCOL_VIOLATION),
846 errmsg("malformed SCRAM message"),
847 errdetail("Unexpected attribute \"%s\" in client-first-message.",
848 sanitize_char(*input))));
849 input++;
850
851 state->client_first_message_bare = pstrdup(input);
852
853 /*
854 * Any mandatory extensions would go here. We don't support any.
855 *
856 * RFC 5802 specifies error code "e=extensions-not-supported" for this,
857 * but it can only be sent in the server-final message. We prefer to fail
858 * immediately (which the RFC also allows).
859 */
860 if (*input == 'm')
861 ereport(ERROR,
862 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
863 errmsg("client requires an unsupported SCRAM extension")));
864
865 /*
866 * Read username. Note: this is ignored. We use the username from the
867 * startup message instead, still it is kept around if provided as it
868 * proves to be useful for debugging purposes.
869 */
870 state->client_username = read_attr_value(&input, 'n');
871
872 /* read nonce and check that it is made of only printable characters */
873 state->client_nonce = read_attr_value(&input, 'r');
874 if (!is_scram_printable(state->client_nonce))
875 ereport(ERROR,
876 (errcode(ERRCODE_PROTOCOL_VIOLATION),
877 errmsg("non-printable characters in SCRAM nonce")));
878
879 /*
880 * There can be any number of optional extensions after this. We don't
881 * support any extensions, so ignore them.
882 */
883 while (*input != '\0')
884 read_any_attr(&input, NULL);
885
886 /* success! */
887 }
888
889 /*
890 * Verify the final nonce contained in the last message received from
891 * client in an exchange.
892 */
893 static bool
verify_final_nonce(scram_state * state)894 verify_final_nonce(scram_state *state)
895 {
896 int client_nonce_len = strlen(state->client_nonce);
897 int server_nonce_len = strlen(state->server_nonce);
898 int final_nonce_len = strlen(state->client_final_nonce);
899
900 if (final_nonce_len != client_nonce_len + server_nonce_len)
901 return false;
902 if (memcmp(state->client_final_nonce, state->client_nonce, client_nonce_len) != 0)
903 return false;
904 if (memcmp(state->client_final_nonce + client_nonce_len, state->server_nonce, server_nonce_len) != 0)
905 return false;
906
907 return true;
908 }
909
910 /*
911 * Verify the client proof contained in the last message received from
912 * client in an exchange.
913 */
914 static bool
verify_client_proof(scram_state * state)915 verify_client_proof(scram_state *state)
916 {
917 uint8 ClientSignature[SCRAM_KEY_LEN];
918 uint8 ClientKey[SCRAM_KEY_LEN];
919 uint8 client_StoredKey[SCRAM_KEY_LEN];
920 scram_HMAC_ctx ctx;
921 int i;
922
923 /* calculate ClientSignature */
924 scram_HMAC_init(&ctx, state->StoredKey, SCRAM_KEY_LEN);
925 scram_HMAC_update(&ctx,
926 state->client_first_message_bare,
927 strlen(state->client_first_message_bare));
928 scram_HMAC_update(&ctx, ",", 1);
929 scram_HMAC_update(&ctx,
930 state->server_first_message,
931 strlen(state->server_first_message));
932 scram_HMAC_update(&ctx, ",", 1);
933 scram_HMAC_update(&ctx,
934 state->client_final_message_without_proof,
935 strlen(state->client_final_message_without_proof));
936 scram_HMAC_final(ClientSignature, &ctx);
937
938 /* Extract the ClientKey that the client calculated from the proof */
939 for (i = 0; i < SCRAM_KEY_LEN; i++)
940 ClientKey[i] = state->ClientProof[i] ^ ClientSignature[i];
941
942 /* Hash it one more time, and compare with StoredKey */
943 scram_H(ClientKey, SCRAM_KEY_LEN, client_StoredKey);
944
945 if (memcmp(client_StoredKey, state->StoredKey, SCRAM_KEY_LEN) != 0)
946 return false;
947
948 return true;
949 }
950
951 /*
952 * Build the first server-side message sent to the client in a SCRAM
953 * communication exchange.
954 */
955 static char *
build_server_first_message(scram_state * state)956 build_server_first_message(scram_state *state)
957 {
958 /*------
959 * The syntax for the server-first-message is: (RFC 5802)
960 *
961 * server-first-message =
962 * [reserved-mext ","] nonce "," salt ","
963 * iteration-count ["," extensions]
964 *
965 * nonce = "r=" c-nonce [s-nonce]
966 * ;; Second part provided by server.
967 *
968 * c-nonce = printable
969 *
970 * s-nonce = printable
971 *
972 * salt = "s=" base64
973 *
974 * iteration-count = "i=" posit-number
975 * ;; A positive number.
976 *
977 * Example:
978 *
979 * r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,s=QSXCR+Q6sek8bf92,i=4096
980 *------
981 */
982
983 /*
984 * Per the spec, the nonce may consist of any printable ASCII characters.
985 * For convenience, however, we don't use the whole range available,
986 * rather, we generate some random bytes, and base64 encode them.
987 */
988 char raw_nonce[SCRAM_RAW_NONCE_LEN];
989 int encoded_len;
990
991 if (!pg_backend_random(raw_nonce, SCRAM_RAW_NONCE_LEN))
992 ereport(ERROR,
993 (errcode(ERRCODE_INTERNAL_ERROR),
994 errmsg("could not generate random nonce")));
995
996 state->server_nonce = palloc(pg_b64_enc_len(SCRAM_RAW_NONCE_LEN) + 1);
997 encoded_len = pg_b64_encode(raw_nonce, SCRAM_RAW_NONCE_LEN, state->server_nonce);
998 state->server_nonce[encoded_len] = '\0';
999
1000 state->server_first_message =
1001 psprintf("r=%s%s,s=%s,i=%u",
1002 state->client_nonce, state->server_nonce,
1003 state->salt, state->iterations);
1004
1005 return pstrdup(state->server_first_message);
1006 }
1007
1008
1009 /*
1010 * Read and parse the final message received from client.
1011 */
1012 static void
read_client_final_message(scram_state * state,char * input)1013 read_client_final_message(scram_state *state, char *input)
1014 {
1015 char attr;
1016 char *channel_binding;
1017 char *value;
1018 char *begin,
1019 *proof;
1020 char *p;
1021 char *client_proof;
1022
1023 begin = p = pstrdup(input);
1024
1025 /*------
1026 * The syntax for the server-first-message is: (RFC 5802)
1027 *
1028 * gs2-header = gs2-cbind-flag "," [ authzid ] ","
1029 * ;; GS2 header for SCRAM
1030 * ;; (the actual GS2 header includes an optional
1031 * ;; flag to indicate that the GSS mechanism is not
1032 * ;; "standard", but since SCRAM is "standard", we
1033 * ;; don't include that flag).
1034 *
1035 * cbind-input = gs2-header [ cbind-data ]
1036 * ;; cbind-data MUST be present for
1037 * ;; gs2-cbind-flag of "p" and MUST be absent
1038 * ;; for "y" or "n".
1039 *
1040 * channel-binding = "c=" base64
1041 * ;; base64 encoding of cbind-input.
1042 *
1043 * proof = "p=" base64
1044 *
1045 * client-final-message-without-proof =
1046 * channel-binding "," nonce [","
1047 * extensions]
1048 *
1049 * client-final-message =
1050 * client-final-message-without-proof "," proof
1051 *------
1052 */
1053
1054 /*
1055 * Read channel-binding. We don't support channel binding, so it's
1056 * expected to always be "biws", which is "n,,", base64-encoded, or
1057 * "eSws", which is "y,,". We also have to check whether the flag is
1058 * the same one that the client originally sent.
1059 */
1060 channel_binding = read_attr_value(&p, 'c');
1061 if (!(strcmp(channel_binding, "biws") == 0 && state->cbind_flag == 'n') &&
1062 !(strcmp(channel_binding, "eSws") == 0 && state->cbind_flag == 'y'))
1063 ereport(ERROR,
1064 (errcode(ERRCODE_PROTOCOL_VIOLATION),
1065 (errmsg("unexpected SCRAM channel-binding attribute in client-final-message"))));
1066 state->client_final_nonce = read_attr_value(&p, 'r');
1067
1068 /* ignore optional extensions */
1069 do
1070 {
1071 proof = p - 1;
1072 value = read_any_attr(&p, &attr);
1073 } while (attr != 'p');
1074
1075 client_proof = palloc(pg_b64_dec_len(strlen(value)));
1076 if (pg_b64_decode(value, strlen(value), client_proof) != SCRAM_KEY_LEN)
1077 ereport(ERROR,
1078 (errcode(ERRCODE_PROTOCOL_VIOLATION),
1079 errmsg("malformed SCRAM message"),
1080 errdetail("Malformed proof in client-final-message.")));
1081 memcpy(state->ClientProof, client_proof, SCRAM_KEY_LEN);
1082 pfree(client_proof);
1083
1084 if (*p != '\0')
1085 ereport(ERROR,
1086 (errcode(ERRCODE_PROTOCOL_VIOLATION),
1087 errmsg("malformed SCRAM message"),
1088 errdetail("Garbage found at the end of client-final-message.")));
1089
1090 state->client_final_message_without_proof = palloc(proof - begin + 1);
1091 memcpy(state->client_final_message_without_proof, input, proof - begin);
1092 state->client_final_message_without_proof[proof - begin] = '\0';
1093 }
1094
1095 /*
1096 * Build the final server-side message of an exchange.
1097 */
1098 static char *
build_server_final_message(scram_state * state)1099 build_server_final_message(scram_state *state)
1100 {
1101 uint8 ServerSignature[SCRAM_KEY_LEN];
1102 char *server_signature_base64;
1103 int siglen;
1104 scram_HMAC_ctx ctx;
1105
1106 /* calculate ServerSignature */
1107 scram_HMAC_init(&ctx, state->ServerKey, SCRAM_KEY_LEN);
1108 scram_HMAC_update(&ctx,
1109 state->client_first_message_bare,
1110 strlen(state->client_first_message_bare));
1111 scram_HMAC_update(&ctx, ",", 1);
1112 scram_HMAC_update(&ctx,
1113 state->server_first_message,
1114 strlen(state->server_first_message));
1115 scram_HMAC_update(&ctx, ",", 1);
1116 scram_HMAC_update(&ctx,
1117 state->client_final_message_without_proof,
1118 strlen(state->client_final_message_without_proof));
1119 scram_HMAC_final(ServerSignature, &ctx);
1120
1121 server_signature_base64 = palloc(pg_b64_enc_len(SCRAM_KEY_LEN) + 1);
1122 siglen = pg_b64_encode((const char *) ServerSignature,
1123 SCRAM_KEY_LEN, server_signature_base64);
1124 server_signature_base64[siglen] = '\0';
1125
1126 /*------
1127 * The syntax for the server-final-message is: (RFC 5802)
1128 *
1129 * verifier = "v=" base64
1130 * ;; base-64 encoded ServerSignature.
1131 *
1132 * server-final-message = (server-error / verifier)
1133 * ["," extensions]
1134 *
1135 *------
1136 */
1137 return psprintf("v=%s", server_signature_base64);
1138 }
1139
1140
1141 /*
1142 * Determinisitcally generate salt for mock authentication, using a SHA256
1143 * hash based on the username and a cluster-level secret key. Returns a
1144 * pointer to a static buffer of size SCRAM_DEFAULT_SALT_LEN.
1145 */
1146 static char *
scram_mock_salt(const char * username)1147 scram_mock_salt(const char *username)
1148 {
1149 pg_sha256_ctx ctx;
1150 static uint8 sha_digest[PG_SHA256_DIGEST_LENGTH];
1151 char *mock_auth_nonce = GetMockAuthenticationNonce();
1152
1153 /*
1154 * Generate salt using a SHA256 hash of the username and the cluster's
1155 * mock authentication nonce. (This works as long as the salt length is
1156 * not larger the SHA256 digest length. If the salt is smaller, the caller
1157 * will just ignore the extra data.)
1158 */
1159 StaticAssertStmt(PG_SHA256_DIGEST_LENGTH >= SCRAM_DEFAULT_SALT_LEN,
1160 "salt length greater than SHA256 digest length");
1161
1162 pg_sha256_init(&ctx);
1163 pg_sha256_update(&ctx, (uint8 *) username, strlen(username));
1164 pg_sha256_update(&ctx, (uint8 *) mock_auth_nonce, MOCK_AUTH_NONCE_LEN);
1165 pg_sha256_final(&ctx, sha_digest);
1166
1167 return (char *) sha_digest;
1168 }
1169