TLA Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * fe-auth-scram.c
4 : * The front-end (client) implementation of SCRAM authentication.
5 : *
6 : * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
7 : * Portions Copyright (c) 1994, Regents of the University of California
8 : *
9 : * IDENTIFICATION
10 : * src/interfaces/libpq/fe-auth-scram.c
11 : *
12 : *-------------------------------------------------------------------------
13 : */
14 :
15 : #include "postgres_fe.h"
16 :
17 : #include "common/base64.h"
18 : #include "common/hmac.h"
19 : #include "common/saslprep.h"
20 : #include "common/scram-common.h"
21 : #include "fe-auth.h"
22 :
23 :
24 : /* The exported SCRAM callback mechanism. */
25 : static void *scram_init(PGconn *conn, const char *password,
26 : const char *sasl_mechanism);
27 : static void scram_exchange(void *opaq, char *input, int inputlen,
28 : char **output, int *outputlen,
29 : bool *done, bool *success);
30 : static bool scram_channel_bound(void *opaq);
31 : static void scram_free(void *opaq);
32 :
33 : const pg_fe_sasl_mech pg_scram_mech = {
34 : scram_init,
35 : scram_exchange,
36 : scram_channel_bound,
37 : scram_free
38 : };
39 :
40 : /*
41 : * Status of exchange messages used for SCRAM authentication via the
42 : * SASL protocol.
43 : */
44 : typedef enum
45 : {
46 : FE_SCRAM_INIT,
47 : FE_SCRAM_NONCE_SENT,
48 : FE_SCRAM_PROOF_SENT,
49 : FE_SCRAM_FINISHED
50 : } fe_scram_state_enum;
51 :
52 : typedef struct
53 : {
54 : fe_scram_state_enum state;
55 :
56 : /* These are supplied by the user */
57 : PGconn *conn;
58 : char *password;
59 : char *sasl_mechanism;
60 :
61 : /* State data depending on the hash type */
62 : pg_cryptohash_type hash_type;
63 : int key_length;
64 :
65 : /* We construct these */
66 : uint8 SaltedPassword[SCRAM_MAX_KEY_LEN];
67 : char *client_nonce;
68 : char *client_first_message_bare;
69 : char *client_final_message_without_proof;
70 :
71 : /* These come from the server-first message */
72 : char *server_first_message;
73 : char *salt;
74 : int saltlen;
75 : int iterations;
76 : char *nonce;
77 :
78 : /* These come from the server-final message */
79 : char *server_final_message;
80 : char ServerSignature[SCRAM_MAX_KEY_LEN];
81 : } fe_scram_state;
82 :
83 : static bool read_server_first_message(fe_scram_state *state, char *input);
84 : static bool read_server_final_message(fe_scram_state *state, char *input);
85 : static char *build_client_first_message(fe_scram_state *state);
86 : static char *build_client_final_message(fe_scram_state *state);
87 : static bool verify_server_signature(fe_scram_state *state, bool *match,
88 : const char **errstr);
89 : static bool calculate_client_proof(fe_scram_state *state,
90 : const char *client_final_message_without_proof,
91 : uint8 *result, const char **errstr);
92 :
93 : /*
94 : * Initialize SCRAM exchange status.
95 : */
96 : static void *
97 GIC 34 : scram_init(PGconn *conn,
98 : const char *password,
99 : const char *sasl_mechanism)
100 : {
101 ECB : fe_scram_state *state;
102 : char *prep_password;
103 : pg_saslprep_rc rc;
104 :
105 GIC 34 : Assert(sasl_mechanism != NULL);
106 :
107 34 : state = (fe_scram_state *) malloc(sizeof(fe_scram_state));
108 34 : if (!state)
109 LBC 0 : return NULL;
110 GIC 34 : memset(state, 0, sizeof(fe_scram_state));
111 CBC 34 : state->conn = conn;
112 34 : state->state = FE_SCRAM_INIT;
113 GNC 34 : state->key_length = SCRAM_SHA_256_KEY_LEN;
114 34 : state->hash_type = PG_SHA256;
115 ECB :
116 GNC 34 : state->sasl_mechanism = strdup(sasl_mechanism);
117 CBC 34 : if (!state->sasl_mechanism)
118 ECB : {
119 LBC 0 : free(state);
120 0 : return NULL;
121 : }
122 ECB :
123 : /* Normalize the password with SASLprep, if possible */
124 GIC 34 : rc = pg_saslprep(password, &prep_password);
125 GBC 34 : if (rc == SASLPREP_OOM)
126 EUB : {
127 UIC 0 : free(state->sasl_mechanism);
128 0 : free(state);
129 0 : return NULL;
130 ECB : }
131 CBC 34 : if (rc != SASLPREP_SUCCESS)
132 : {
133 GBC 2 : prep_password = strdup(password);
134 2 : if (!prep_password)
135 EUB : {
136 UIC 0 : free(state->sasl_mechanism);
137 LBC 0 : free(state);
138 UIC 0 : return NULL;
139 ECB : }
140 : }
141 GIC 34 : state->password = prep_password;
142 EUB :
143 GBC 34 : return state;
144 EUB : }
145 :
146 : /*
147 ECB : * Return true if channel binding was employed and the SCRAM exchange
148 : * completed. This should be used after a successful exchange to determine
149 : * whether the server authenticated itself to the client.
150 : *
151 : * Note that the caller must also ensure that the exchange was actually
152 : * successful.
153 : */
154 : static bool
155 GIC 3 : scram_channel_bound(void *opaq)
156 : {
157 3 : fe_scram_state *state = (fe_scram_state *) opaq;
158 :
159 : /* no SCRAM exchange done */
160 3 : if (state == NULL)
161 LBC 0 : return false;
162 :
163 ECB : /* SCRAM exchange not completed */
164 GIC 3 : if (state->state != FE_SCRAM_FINISHED)
165 UIC 0 : return false;
166 ECB :
167 EUB : /* channel binding mechanism not used */
168 GIC 3 : if (strcmp(state->sasl_mechanism, SCRAM_SHA_256_PLUS_NAME) != 0)
169 UIC 0 : return false;
170 ECB :
171 EUB : /* all clear! */
172 GIC 3 : return true;
173 : }
174 ECB :
175 EUB : /*
176 : * Free SCRAM exchange status
177 : */
178 ECB : static void
179 GIC 34 : scram_free(void *opaq)
180 : {
181 34 : fe_scram_state *state = (fe_scram_state *) opaq;
182 :
183 GNC 34 : free(state->password);
184 34 : free(state->sasl_mechanism);
185 ECB :
186 : /* client messages */
187 GNC 34 : free(state->client_nonce);
188 34 : free(state->client_first_message_bare);
189 34 : free(state->client_final_message_without_proof);
190 ECB :
191 : /* first message from server */
192 GNC 34 : free(state->server_first_message);
193 34 : free(state->salt);
194 34 : free(state->nonce);
195 ECB :
196 : /* final message from server */
197 GNC 34 : free(state->server_final_message);
198 :
199 GIC 34 : free(state);
200 34 : }
201 :
202 : /*
203 ECB : * Exchange a SCRAM message with backend.
204 : */
205 : static void
206 GIC 96 : scram_exchange(void *opaq, char *input, int inputlen,
207 ECB : char **output, int *outputlen,
208 : bool *done, bool *success)
209 : {
210 GIC 96 : fe_scram_state *state = (fe_scram_state *) opaq;
211 CBC 96 : PGconn *conn = state->conn;
212 96 : const char *errstr = NULL;
213 ECB :
214 CBC 96 : *done = false;
215 GIC 96 : *success = false;
216 96 : *output = NULL;
217 96 : *outputlen = 0;
218 :
219 : /*
220 ECB : * Check that the input length agrees with the string length of the input.
221 : * We can ignore inputlen after this.
222 : */
223 GIC 96 : if (state->state != FE_SCRAM_INIT)
224 EUB : {
225 GBC 62 : if (inputlen == 0)
226 : {
227 UNC 0 : libpq_append_conn_error(conn, "malformed SCRAM message (empty message)");
228 UBC 0 : goto error;
229 EUB : }
230 GIC 62 : if (inputlen != strlen(input))
231 : {
232 UNC 0 : libpq_append_conn_error(conn, "malformed SCRAM message (length mismatch)");
233 UIC 0 : goto error;
234 ECB : }
235 : }
236 :
237 CBC 96 : switch (state->state)
238 EUB : {
239 GIC 34 : case FE_SCRAM_INIT:
240 ECB : /* Begin the SCRAM handshake, by sending client nonce */
241 CBC 34 : *output = build_client_first_message(state);
242 34 : if (*output == NULL)
243 LBC 0 : goto error;
244 :
245 CBC 34 : *outputlen = strlen(*output);
246 GIC 34 : *done = false;
247 CBC 34 : state->state = FE_SCRAM_NONCE_SENT;
248 GBC 34 : break;
249 :
250 CBC 34 : case FE_SCRAM_NONCE_SENT:
251 ECB : /* Receive salt and server nonce, send response. */
252 GBC 34 : if (!read_server_first_message(state, input))
253 UIC 0 : goto error;
254 ECB :
255 CBC 34 : *output = build_client_final_message(state);
256 34 : if (*output == NULL)
257 LBC 0 : goto error;
258 :
259 CBC 34 : *outputlen = strlen(*output);
260 GIC 34 : *done = false;
261 CBC 34 : state->state = FE_SCRAM_PROOF_SENT;
262 GBC 34 : break;
263 :
264 GIC 28 : case FE_SCRAM_PROOF_SENT:
265 : /* Receive server signature */
266 28 : if (!read_server_final_message(state, input))
267 UIC 0 : goto error;
268 ECB :
269 : /*
270 EUB : * Verify server signature, to make sure we're talking to the
271 : * genuine server.
272 : */
273 GIC 28 : if (!verify_server_signature(state, success, &errstr))
274 ECB : {
275 UNC 0 : libpq_append_conn_error(conn, "could not verify server signature: %s", errstr);
276 UIC 0 : goto error;
277 ECB : }
278 :
279 CBC 28 : if (!*success)
280 ECB : {
281 UNC 0 : libpq_append_conn_error(conn, "incorrect server signature");
282 : }
283 GBC 28 : *done = true;
284 28 : state->state = FE_SCRAM_FINISHED;
285 GNC 28 : state->conn->client_finished_auth = true;
286 GIC 28 : break;
287 ECB :
288 UIC 0 : default:
289 EUB : /* shouldn't happen */
290 UNC 0 : libpq_append_conn_error(conn, "invalid SCRAM exchange state");
291 UIC 0 : goto error;
292 : }
293 GIC 96 : return;
294 :
295 UIC 0 : error:
296 0 : *done = true;
297 0 : *success = false;
298 : }
299 :
300 : /*
301 : * Read value for an attribute part of a SCRAM message.
302 ECB : *
303 : * The buffer at **input is destructively modified, and *input is
304 : * advanced over the "attr=value" string and any following comma.
305 : *
306 : * On failure, append an error message to *errorMessage and return NULL.
307 : */
308 : static char *
309 GBC 130 : read_attr_value(char **input, char attr, PQExpBuffer errorMessage)
310 : {
311 GIC 130 : char *begin = *input;
312 EUB : char *end;
313 :
314 CBC 130 : if (*begin != attr)
315 : {
316 UNC 0 : libpq_append_error(errorMessage,
317 : "malformed SCRAM message (attribute \"%c\" expected)",
318 : attr);
319 UIC 0 : return NULL;
320 : }
321 GBC 130 : begin++;
322 :
323 CBC 130 : if (*begin != '=')
324 : {
325 UNC 0 : libpq_append_error(errorMessage,
326 : "malformed SCRAM message (expected character \"=\" for attribute \"%c\")",
327 : attr);
328 UIC 0 : return NULL;
329 ECB : }
330 GIC 130 : begin++;
331 ECB :
332 CBC 130 : end = begin;
333 GIC 3944 : while (*end && *end != ',')
334 3814 : end++;
335 ECB :
336 GIC 130 : if (*end)
337 ECB : {
338 GIC 68 : *end = '\0';
339 68 : *input = end + 1;
340 : }
341 : else
342 62 : *input = end;
343 :
344 CBC 130 : return begin;
345 : }
346 ECB :
347 : /*
348 : * Build the first exchange message sent by the client.
349 : */
350 : static char *
351 GIC 34 : build_client_first_message(fe_scram_state *state)
352 : {
353 34 : PGconn *conn = state->conn;
354 : char raw_nonce[SCRAM_RAW_NONCE_LEN + 1];
355 : char *result;
356 : int channel_info_len;
357 ECB : int encoded_len;
358 : PQExpBufferData buf;
359 EUB :
360 : /*
361 : * Generate a "raw" nonce. This is converted to ASCII-printable form by
362 : * base64-encoding it.
363 ECB : */
364 GIC 34 : if (!pg_strong_random(raw_nonce, SCRAM_RAW_NONCE_LEN))
365 ECB : {
366 UNC 0 : libpq_append_conn_error(conn, "could not generate nonce");
367 UBC 0 : return NULL;
368 EUB : }
369 :
370 CBC 34 : encoded_len = pg_b64_enc_len(SCRAM_RAW_NONCE_LEN);
371 : /* don't forget the zero-terminator */
372 34 : state->client_nonce = malloc(encoded_len + 1);
373 GIC 34 : if (state->client_nonce == NULL)
374 EUB : {
375 UNC 0 : libpq_append_conn_error(conn, "out of memory");
376 LBC 0 : return NULL;
377 : }
378 GIC 34 : encoded_len = pg_b64_encode(raw_nonce, SCRAM_RAW_NONCE_LEN,
379 : state->client_nonce, encoded_len);
380 34 : if (encoded_len < 0)
381 : {
382 UNC 0 : libpq_append_conn_error(conn, "could not encode nonce");
383 UIC 0 : return NULL;
384 ECB : }
385 GIC 34 : state->client_nonce[encoded_len] = '\0';
386 :
387 : /*
388 : * Generate message. The username is left empty as the backend uses the
389 ECB : * value provided by the startup packet. Also, as this username is not
390 : * prepared with SASLprep, the message parsing would fail if it includes
391 : * '=' or ',' characters.
392 : */
393 :
394 GIC 34 : initPQExpBuffer(&buf);
395 ECB :
396 : /*
397 : * First build the gs2-header with channel binding information.
398 : */
399 GIC 34 : if (strcmp(state->sasl_mechanism, SCRAM_SHA_256_PLUS_NAME) == 0)
400 : {
401 GBC 5 : Assert(conn->ssl_in_use);
402 GIC 5 : appendPQExpBufferStr(&buf, "p=tls-server-end-point");
403 : }
404 : #ifdef HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH
405 29 : else if (conn->channel_binding[0] != 'd' && /* disable */
406 27 : conn->ssl_in_use)
407 : {
408 : /*
409 ECB : * Client supports channel binding, but thinks the server does not.
410 : */
411 UIC 0 : appendPQExpBufferChar(&buf, 'y');
412 ECB : }
413 EUB : #endif
414 : else
415 ECB : {
416 : /*
417 : * Client does not support channel binding, or has disabled it.
418 : */
419 GBC 29 : appendPQExpBufferChar(&buf, 'n');
420 : }
421 :
422 GIC 34 : if (PQExpBufferDataBroken(buf))
423 UIC 0 : goto oom_error;
424 :
425 CBC 34 : channel_info_len = buf.len;
426 ECB :
427 GBC 34 : appendPQExpBuffer(&buf, ",,n=,r=%s", state->client_nonce);
428 GIC 34 : if (PQExpBufferDataBroken(buf))
429 LBC 0 : goto oom_error;
430 ECB :
431 EUB : /*
432 : * The first message content needs to be saved without channel binding
433 ECB : * information.
434 : */
435 GIC 34 : state->client_first_message_bare = strdup(buf.data + channel_info_len + 2);
436 GBC 34 : if (!state->client_first_message_bare)
437 UBC 0 : goto oom_error;
438 EUB :
439 GBC 34 : result = strdup(buf.data);
440 GIC 34 : if (result == NULL)
441 UIC 0 : goto oom_error;
442 :
443 GIC 34 : termPQExpBuffer(&buf);
444 34 : return result;
445 :
446 LBC 0 : oom_error:
447 UIC 0 : termPQExpBuffer(&buf);
448 UNC 0 : libpq_append_conn_error(conn, "out of memory");
449 UIC 0 : return NULL;
450 : }
451 :
452 ECB : /*
453 : * Build the final exchange message sent from the client.
454 : */
455 : static char *
456 GIC 34 : build_client_final_message(fe_scram_state *state)
457 : {
458 : PQExpBufferData buf;
459 34 : PGconn *conn = state->conn;
460 : uint8 client_proof[SCRAM_MAX_KEY_LEN];
461 : char *result;
462 : int encoded_len;
463 34 : const char *errstr = NULL;
464 ECB :
465 GIC 34 : initPQExpBuffer(&buf);
466 :
467 ECB : /*
468 : * Construct client-final-message-without-proof. We need to remember it
469 : * for verifying the server proof in the final step of authentication.
470 : *
471 : * The channel binding flag handling (p/y/n) must be consistent with
472 : * build_client_first_message(), because the server will check that it's
473 : * the same flag both times.
474 : */
475 GIC 34 : if (strcmp(state->sasl_mechanism, SCRAM_SHA_256_PLUS_NAME) == 0)
476 ECB : {
477 : #ifdef HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH
478 CBC 5 : char *cbind_data = NULL;
479 GIC 5 : size_t cbind_data_len = 0;
480 : size_t cbind_header_len;
481 EUB : char *cbind_input;
482 : size_t cbind_input_len;
483 : int encoded_cbind_len;
484 :
485 ECB : /* Fetch hash data of server's SSL certificate */
486 : cbind_data =
487 GIC 5 : pgtls_get_peer_certificate_hash(state->conn,
488 ECB : &cbind_data_len);
489 CBC 5 : if (cbind_data == NULL)
490 ECB : {
491 : /* error message is already set on error */
492 UIC 0 : termPQExpBuffer(&buf);
493 UBC 0 : return NULL;
494 EUB : }
495 :
496 CBC 5 : appendPQExpBufferStr(&buf, "c=");
497 ECB :
498 : /* p=type,, */
499 CBC 5 : cbind_header_len = strlen("p=tls-server-end-point,,");
500 5 : cbind_input_len = cbind_header_len + cbind_data_len;
501 GIC 5 : cbind_input = malloc(cbind_input_len);
502 GBC 5 : if (!cbind_input)
503 EUB : {
504 UBC 0 : free(cbind_data);
505 UIC 0 : goto oom_error;
506 ECB : }
507 CBC 5 : memcpy(cbind_input, "p=tls-server-end-point,,", cbind_header_len);
508 GIC 5 : memcpy(cbind_input + cbind_header_len, cbind_data, cbind_data_len);
509 ECB :
510 GIC 5 : encoded_cbind_len = pg_b64_enc_len(cbind_input_len);
511 GBC 5 : if (!enlargePQExpBuffer(&buf, encoded_cbind_len))
512 EUB : {
513 UBC 0 : free(cbind_data);
514 0 : free(cbind_input);
515 UIC 0 : goto oom_error;
516 EUB : }
517 GIC 5 : encoded_cbind_len = pg_b64_encode(cbind_input, cbind_input_len,
518 CBC 5 : buf.data + buf.len,
519 ECB : encoded_cbind_len);
520 GIC 5 : if (encoded_cbind_len < 0)
521 ECB : {
522 LBC 0 : free(cbind_data);
523 UIC 0 : free(cbind_input);
524 0 : termPQExpBuffer(&buf);
525 0 : appendPQExpBufferStr(&conn->errorMessage,
526 : "could not encode cbind data for channel binding\n");
527 0 : return NULL;
528 : }
529 GIC 5 : buf.len += encoded_cbind_len;
530 5 : buf.data[buf.len] = '\0';
531 :
532 5 : free(cbind_data);
533 5 : free(cbind_input);
534 : #else
535 ECB : /*
536 : * Chose channel binding, but the SSL library doesn't support it.
537 EUB : * Shouldn't happen.
538 : */
539 : termPQExpBuffer(&buf);
540 ECB : appendPQExpBufferStr(&conn->errorMessage,
541 : "channel binding not supported by this build\n");
542 : return NULL;
543 EUB : #endif /* HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH */
544 : }
545 ECB : #ifdef HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH
546 CBC 29 : else if (conn->channel_binding[0] != 'd' && /* disable */
547 GBC 27 : conn->ssl_in_use)
548 UIC 0 : appendPQExpBufferStr(&buf, "c=eSws"); /* base64 of "y,," */
549 ECB : #endif
550 : else
551 GBC 29 : appendPQExpBufferStr(&buf, "c=biws"); /* base64 of "n,," */
552 :
553 GIC 34 : if (PQExpBufferDataBroken(buf))
554 LBC 0 : goto oom_error;
555 ECB :
556 GIC 34 : appendPQExpBuffer(&buf, ",r=%s", state->nonce);
557 34 : if (PQExpBufferDataBroken(buf))
558 UBC 0 : goto oom_error;
559 EUB :
560 GBC 34 : state->client_final_message_without_proof = strdup(buf.data);
561 GIC 34 : if (state->client_final_message_without_proof == NULL)
562 UIC 0 : goto oom_error;
563 ECB :
564 : /* Append proof to it, to form client-final-message. */
565 CBC 34 : if (!calculate_client_proof(state,
566 GBC 34 : state->client_final_message_without_proof,
567 ECB : client_proof, &errstr))
568 : {
569 LBC 0 : termPQExpBuffer(&buf);
570 UNC 0 : libpq_append_conn_error(conn, "could not calculate client proof: %s", errstr);
571 UBC 0 : return NULL;
572 EUB : }
573 :
574 GIC 34 : appendPQExpBufferStr(&buf, ",p=");
575 GNC 34 : encoded_len = pg_b64_enc_len(state->key_length);
576 CBC 34 : if (!enlargePQExpBuffer(&buf, encoded_len))
577 UIC 0 : goto oom_error;
578 CBC 34 : encoded_len = pg_b64_encode((char *) client_proof,
579 : state->key_length,
580 GBC 34 : buf.data + buf.len,
581 : encoded_len);
582 CBC 34 : if (encoded_len < 0)
583 ECB : {
584 UIC 0 : termPQExpBuffer(&buf);
585 UNC 0 : libpq_append_conn_error(conn, "could not encode client proof");
586 UBC 0 : return NULL;
587 EUB : }
588 GIC 34 : buf.len += encoded_len;
589 34 : buf.data[buf.len] = '\0';
590 :
591 34 : result = strdup(buf.data);
592 34 : if (result == NULL)
593 UIC 0 : goto oom_error;
594 ECB :
595 GIC 34 : termPQExpBuffer(&buf);
596 CBC 34 : return result;
597 :
598 UIC 0 : oom_error:
599 0 : termPQExpBuffer(&buf);
600 UNC 0 : libpq_append_conn_error(conn, "out of memory");
601 UIC 0 : return NULL;
602 ECB : }
603 :
604 : /*
605 EUB : * Read the first exchange message coming from the server.
606 : */
607 : static bool
608 GIC 34 : read_server_first_message(fe_scram_state *state, char *input)
609 : {
610 CBC 34 : PGconn *conn = state->conn;
611 : char *iterations_str;
612 ECB : char *endptr;
613 : char *encoded_salt;
614 : char *nonce;
615 EUB : int decoded_salt_len;
616 :
617 GIC 34 : state->server_first_message = strdup(input);
618 34 : if (state->server_first_message == NULL)
619 ECB : {
620 UNC 0 : libpq_append_conn_error(conn, "out of memory");
621 UBC 0 : return false;
622 EUB : }
623 :
624 : /* parse the message */
625 CBC 34 : nonce = read_attr_value(&input, 'r',
626 ECB : &conn->errorMessage);
627 GIC 34 : if (nonce == NULL)
628 EUB : {
629 : /* read_attr_value() has appended an error string */
630 UIC 0 : return false;
631 : }
632 ECB :
633 : /* Verify immediately that the server used our part of the nonce */
634 GIC 34 : if (strlen(nonce) < strlen(state->client_nonce) ||
635 34 : memcmp(nonce, state->client_nonce, strlen(state->client_nonce)) != 0)
636 EUB : {
637 UNC 0 : libpq_append_conn_error(conn, "invalid SCRAM response (nonce mismatch)");
638 LBC 0 : return false;
639 ECB : }
640 :
641 GBC 34 : state->nonce = strdup(nonce);
642 34 : if (state->nonce == NULL)
643 : {
644 UNC 0 : libpq_append_conn_error(conn, "out of memory");
645 UIC 0 : return false;
646 : }
647 ECB :
648 GIC 34 : encoded_salt = read_attr_value(&input, 's', &conn->errorMessage);
649 GBC 34 : if (encoded_salt == NULL)
650 EUB : {
651 : /* read_attr_value() has appended an error string */
652 UIC 0 : return false;
653 ECB : }
654 CBC 34 : decoded_salt_len = pg_b64_dec_len(strlen(encoded_salt));
655 GIC 34 : state->salt = malloc(decoded_salt_len);
656 34 : if (state->salt == NULL)
657 EUB : {
658 UNC 0 : libpq_append_conn_error(conn, "out of memory");
659 LBC 0 : return false;
660 : }
661 GBC 68 : state->saltlen = pg_b64_decode(encoded_salt,
662 34 : strlen(encoded_salt),
663 : state->salt,
664 : decoded_salt_len);
665 CBC 34 : if (state->saltlen < 0)
666 EUB : {
667 UNC 0 : libpq_append_conn_error(conn, "malformed SCRAM message (invalid salt)");
668 UIC 0 : return false;
669 : }
670 :
671 GIC 34 : iterations_str = read_attr_value(&input, 'i', &conn->errorMessage);
672 34 : if (iterations_str == NULL)
673 : {
674 ECB : /* read_attr_value() has appended an error string */
675 UIC 0 : return false;
676 ECB : }
677 GIC 34 : state->iterations = strtol(iterations_str, &endptr, 10);
678 34 : if (*endptr != '\0' || state->iterations < 1)
679 : {
680 UNC 0 : libpq_append_conn_error(conn, "malformed SCRAM message (invalid iteration count)");
681 LBC 0 : return false;
682 : }
683 EUB :
684 GBC 34 : if (*input != '\0')
685 UNC 0 : libpq_append_conn_error(conn, "malformed SCRAM message (garbage at end of server-first-message)");
686 :
687 CBC 34 : return true;
688 : }
689 EUB :
690 : /*
691 : * Read the final exchange message coming from the server.
692 : */
693 : static bool
694 GIC 28 : read_server_final_message(fe_scram_state *state, char *input)
695 EUB : {
696 GIC 28 : PGconn *conn = state->conn;
697 EUB : char *encoded_server_signature;
698 : char *decoded_server_signature;
699 : int server_signature_len;
700 :
701 GIC 28 : state->server_final_message = strdup(input);
702 28 : if (!state->server_final_message)
703 ECB : {
704 UNC 0 : libpq_append_conn_error(conn, "out of memory");
705 UIC 0 : return false;
706 : }
707 EUB :
708 : /* Check for error result. */
709 GIC 28 : if (*input == 'e')
710 ECB : {
711 UBC 0 : char *errmsg = read_attr_value(&input, 'e',
712 : &conn->errorMessage);
713 ECB :
714 LBC 0 : if (errmsg == NULL)
715 ECB : {
716 : /* read_attr_value() has appended an error message */
717 UBC 0 : return false;
718 EUB : }
719 UNC 0 : libpq_append_conn_error(conn, "error received from server in SCRAM exchange: %s",
720 : errmsg);
721 LBC 0 : return false;
722 : }
723 :
724 ECB : /* Parse the message. */
725 GIC 28 : encoded_server_signature = read_attr_value(&input, 'v',
726 EUB : &conn->errorMessage);
727 GBC 28 : if (encoded_server_signature == NULL)
728 EUB : {
729 : /* read_attr_value() has appended an error message */
730 LBC 0 : return false;
731 ECB : }
732 :
733 GIC 28 : if (*input != '\0')
734 UNC 0 : libpq_append_conn_error(conn, "malformed SCRAM message (garbage at end of server-final-message)");
735 :
736 GIC 28 : server_signature_len = pg_b64_dec_len(strlen(encoded_server_signature));
737 28 : decoded_server_signature = malloc(server_signature_len);
738 28 : if (!decoded_server_signature)
739 : {
740 UNC 0 : libpq_append_conn_error(conn, "out of memory");
741 LBC 0 : return false;
742 : }
743 :
744 GIC 28 : server_signature_len = pg_b64_decode(encoded_server_signature,
745 28 : strlen(encoded_server_signature),
746 : decoded_server_signature,
747 : server_signature_len);
748 GNC 28 : if (server_signature_len != state->key_length)
749 : {
750 UIC 0 : free(decoded_server_signature);
751 UNC 0 : libpq_append_conn_error(conn, "malformed SCRAM message (invalid server signature)");
752 UIC 0 : return false;
753 EUB : }
754 GNC 28 : memcpy(state->ServerSignature, decoded_server_signature,
755 28 : state->key_length);
756 GIC 28 : free(decoded_server_signature);
757 :
758 28 : return true;
759 : }
760 :
761 : /*
762 ECB : * Calculate the client proof, part of the final exchange message sent
763 : * by the client. Returns true on success, false on failure with *errstr
764 : * pointing to a message about the error details.
765 : */
766 : static bool
767 CBC 34 : calculate_client_proof(fe_scram_state *state,
768 ECB : const char *client_final_message_without_proof,
769 : uint8 *result, const char **errstr)
770 : {
771 : uint8 StoredKey[SCRAM_MAX_KEY_LEN];
772 : uint8 ClientKey[SCRAM_MAX_KEY_LEN];
773 : uint8 ClientSignature[SCRAM_MAX_KEY_LEN];
774 : int i;
775 : pg_hmac_ctx *ctx;
776 :
777 GNC 34 : ctx = pg_hmac_create(state->hash_type);
778 CBC 34 : if (ctx == NULL)
779 ECB : {
780 LBC 0 : *errstr = pg_hmac_error(NULL); /* returns OOM */
781 0 : return false;
782 ECB : }
783 :
784 : /*
785 : * Calculate SaltedPassword, and store it in 'state' so that we can reuse
786 : * it later in verify_server_signature.
787 : */
788 GNC 34 : if (scram_SaltedPassword(state->password, state->hash_type,
789 34 : state->key_length, state->salt, state->saltlen,
790 GIC 34 : state->iterations, state->SaltedPassword,
791 GBC 34 : errstr) < 0 ||
792 GNC 34 : scram_ClientKey(state->SaltedPassword, state->hash_type,
793 34 : state->key_length, ClientKey, errstr) < 0 ||
794 34 : scram_H(ClientKey, state->hash_type, state->key_length,
795 : StoredKey, errstr) < 0)
796 : {
797 : /* errstr is already filled here */
798 LBC 0 : pg_hmac_free(ctx);
799 0 : return false;
800 : }
801 ECB :
802 GNC 68 : if (pg_hmac_init(ctx, StoredKey, state->key_length) < 0 ||
803 GIC 34 : pg_hmac_update(ctx,
804 34 : (uint8 *) state->client_first_message_bare,
805 68 : strlen(state->client_first_message_bare)) < 0 ||
806 68 : pg_hmac_update(ctx, (uint8 *) ",", 1) < 0 ||
807 34 : pg_hmac_update(ctx,
808 34 : (uint8 *) state->server_first_message,
809 68 : strlen(state->server_first_message)) < 0 ||
810 68 : pg_hmac_update(ctx, (uint8 *) ",", 1) < 0 ||
811 34 : pg_hmac_update(ctx,
812 : (uint8 *) client_final_message_without_proof,
813 CBC 34 : strlen(client_final_message_without_proof)) < 0 ||
814 GNC 34 : pg_hmac_final(ctx, ClientSignature, state->key_length) < 0)
815 : {
816 UIC 0 : *errstr = pg_hmac_error(ctx);
817 0 : pg_hmac_free(ctx);
818 0 : return false;
819 : }
820 ECB :
821 GNC 1122 : for (i = 0; i < state->key_length; i++)
822 GIC 1088 : result[i] = ClientKey[i] ^ ClientSignature[i];
823 EUB :
824 GBC 34 : pg_hmac_free(ctx);
825 GIC 34 : return true;
826 : }
827 ECB :
828 : /*
829 : * Validate the server signature, received as part of the final exchange
830 : * message received from the server. *match tracks if the server signature
831 EUB : * matched or not. Returns true if the server signature got verified, and
832 : * false for a processing error with *errstr pointing to a message about the
833 : * error details.
834 : */
835 : static bool
836 CBC 28 : verify_server_signature(fe_scram_state *state, bool *match,
837 ECB : const char **errstr)
838 : {
839 : uint8 expected_ServerSignature[SCRAM_MAX_KEY_LEN];
840 : uint8 ServerKey[SCRAM_MAX_KEY_LEN];
841 : pg_hmac_ctx *ctx;
842 :
843 GNC 28 : ctx = pg_hmac_create(state->hash_type);
844 CBC 28 : if (ctx == NULL)
845 ECB : {
846 LBC 0 : *errstr = pg_hmac_error(NULL); /* returns OOM */
847 0 : return false;
848 ECB : }
849 :
850 GNC 28 : if (scram_ServerKey(state->SaltedPassword, state->hash_type,
851 : state->key_length, ServerKey, errstr) < 0)
852 EUB : {
853 : /* errstr is filled already */
854 UBC 0 : pg_hmac_free(ctx);
855 UIC 0 : return false;
856 : }
857 ECB :
858 : /* calculate ServerSignature */
859 GNC 56 : if (pg_hmac_init(ctx, ServerKey, state->key_length) < 0 ||
860 CBC 28 : pg_hmac_update(ctx,
861 28 : (uint8 *) state->client_first_message_bare,
862 GBC 56 : strlen(state->client_first_message_bare)) < 0 ||
863 GIC 56 : pg_hmac_update(ctx, (uint8 *) ",", 1) < 0 ||
864 CBC 28 : pg_hmac_update(ctx,
865 GIC 28 : (uint8 *) state->server_first_message,
866 CBC 56 : strlen(state->server_first_message)) < 0 ||
867 GIC 56 : pg_hmac_update(ctx, (uint8 *) ",", 1) < 0 ||
868 28 : pg_hmac_update(ctx,
869 28 : (uint8 *) state->client_final_message_without_proof,
870 56 : strlen(state->client_final_message_without_proof)) < 0 ||
871 28 : pg_hmac_final(ctx, expected_ServerSignature,
872 GNC 28 : state->key_length) < 0)
873 : {
874 UIC 0 : *errstr = pg_hmac_error(ctx);
875 0 : pg_hmac_free(ctx);
876 LBC 0 : return false;
877 : }
878 :
879 GIC 28 : pg_hmac_free(ctx);
880 :
881 : /* signature processed, so now check after it */
882 GNC 28 : if (memcmp(expected_ServerSignature, state->ServerSignature,
883 28 : state->key_length) != 0)
884 UIC 0 : *match = false;
885 : else
886 GIC 28 : *match = true;
887 :
888 28 : return true;
889 : }
890 ECB :
891 : /*
892 : * Build a new SCRAM secret.
893 EUB : *
894 : * On error, returns NULL and sets *errstr to point to a message about the
895 : * error details.
896 ECB : */
897 : char *
898 GNC 1 : pg_fe_scram_build_secret(const char *password, int iterations, const char **errstr)
899 : {
900 ECB : char *prep_password;
901 : pg_saslprep_rc rc;
902 EUB : char saltbuf[SCRAM_DEFAULT_SALT_LEN];
903 : char *result;
904 :
905 : /*
906 : * Normalize the password with SASLprep. If that doesn't work, because
907 ECB : * the password isn't valid UTF-8 or contains prohibited characters, just
908 : * proceed with the original password. (See comments at the top of
909 : * auth-scram.c.)
910 : */
911 GIC 1 : rc = pg_saslprep(password, &prep_password);
912 CBC 1 : if (rc == SASLPREP_OOM)
913 : {
914 LBC 0 : *errstr = libpq_gettext("out of memory");
915 UIC 0 : return NULL;
916 : }
917 GIC 1 : if (rc == SASLPREP_SUCCESS)
918 1 : password = (const char *) prep_password;
919 :
920 : /* Generate a random salt */
921 1 : if (!pg_strong_random(saltbuf, SCRAM_DEFAULT_SALT_LEN))
922 : {
923 UIC 0 : *errstr = libpq_gettext("could not generate random salt");
924 UNC 0 : free(prep_password);
925 UIC 0 : return NULL;
926 : }
927 :
928 GNC 1 : result = scram_build_secret(PG_SHA256, SCRAM_SHA_256_KEY_LEN, saltbuf,
929 : SCRAM_DEFAULT_SALT_LEN,
930 : iterations, password,
931 : errstr);
932 :
933 1 : free(prep_password);
934 :
935 GIC 1 : return result;
936 : }
|