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