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