mirror of
https://github.com/postgres/postgres.git
synced 2026-04-15 22:10:45 -04:00
There are some problems with the tls-unique channel binding type. It's not supported by all SSL libraries, and strictly speaking it's not defined for TLS 1.3 at all, even though at least in OpenSSL, the functions used for it still seem to work with TLS 1.3 connections. And since we had no mechanism to negotiate what channel binding type to use, there would be awkward interoperability issues if a server only supported some channel binding types. tls-server-end-point seems feasible to support with any SSL library, so let's just stick to that. This removes the scram_channel_binding libpq option altogether, since there is now only one supported channel binding type. This also removes all the channel binding tests from the SSL test suite. They were really just testing the scram_channel_binding option, which is now gone. Channel binding is used if both client and server support it, so it is used in the existing tests. It would be good to have some tests specifically for channel binding, to make sure it really is used, and the different combinations of a client and a server that support or doesn't support it. The current set of settings we have make it hard to write such tests, but I did test those things manually, by disabling HAVE_BE_TLS_GET_CERTIFICATE_HASH and/or HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH. I also removed the SCRAM_CHANNEL_BINDING_TLS_END_POINT constant. This is a matter of taste, but IMO it's more readable to just use the "tls-server-end-point" string. Refactor the checks on whether the SSL library supports the functions needed for tls-server-end-point channel binding. Now the server won't advertise, and the client won't choose, the SCRAM-SHA-256-PLUS variant, if compiled with an OpenSSL version too old to support it. In the passing, add some sanity checks to check that the chosen SASL mechanism, SCRAM-SHA-256 or SCRAM-SHA-256-PLUS, matches whether the SCRAM exchange used channel binding or not. For example, if the client selects the non-channel-binding variant SCRAM-SHA-256, but in the SCRAM message uses channel binding anyway. It's harmless from a security point of view, I believe, and I'm not sure if there are some other conditions that would cause the connection to fail, but it seems better to be strict about these things and check explicitly. Discussion: https://www.postgresql.org/message-id/ec787074-2305-c6f4-86aa-6902f98485a4%40iki.fi
70 lines
2.2 KiB
C
70 lines
2.2 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* scram-common.h
|
|
* Declarations for helper functions used for SCRAM authentication
|
|
*
|
|
* Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
* src/include/common/scram-common.h
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#ifndef SCRAM_COMMON_H
|
|
#define SCRAM_COMMON_H
|
|
|
|
#include "common/sha2.h"
|
|
|
|
/* Name of SCRAM mechanisms per IANA */
|
|
#define SCRAM_SHA_256_NAME "SCRAM-SHA-256"
|
|
#define SCRAM_SHA_256_PLUS_NAME "SCRAM-SHA-256-PLUS" /* with channel binding */
|
|
|
|
/* Length of SCRAM keys (client and server) */
|
|
#define SCRAM_KEY_LEN PG_SHA256_DIGEST_LENGTH
|
|
|
|
/* length of HMAC */
|
|
#define SHA256_HMAC_B PG_SHA256_BLOCK_LENGTH
|
|
|
|
/*
|
|
* Size of random nonce generated in the authentication exchange. This
|
|
* is in "raw" number of bytes, the actual nonces sent over the wire are
|
|
* encoded using only ASCII-printable characters.
|
|
*/
|
|
#define SCRAM_RAW_NONCE_LEN 18
|
|
|
|
/*
|
|
* Length of salt when generating new verifiers, in bytes. (It will be stored
|
|
* and sent over the wire encoded in Base64.) 16 bytes is what the example in
|
|
* RFC 7677 uses.
|
|
*/
|
|
#define SCRAM_DEFAULT_SALT_LEN 16
|
|
|
|
/*
|
|
* Default number of iterations when generating verifier. Should be at least
|
|
* 4096 per RFC 7677.
|
|
*/
|
|
#define SCRAM_DEFAULT_ITERATIONS 4096
|
|
|
|
/*
|
|
* Context data for HMAC used in SCRAM authentication.
|
|
*/
|
|
typedef struct
|
|
{
|
|
pg_sha256_ctx sha256ctx;
|
|
uint8 k_opad[SHA256_HMAC_B];
|
|
} scram_HMAC_ctx;
|
|
|
|
extern void scram_HMAC_init(scram_HMAC_ctx *ctx, const uint8 *key, int keylen);
|
|
extern void scram_HMAC_update(scram_HMAC_ctx *ctx, const char *str, int slen);
|
|
extern void scram_HMAC_final(uint8 *result, scram_HMAC_ctx *ctx);
|
|
|
|
extern void scram_SaltedPassword(const char *password, const char *salt,
|
|
int saltlen, int iterations, uint8 *result);
|
|
extern void scram_H(const uint8 *str, int len, uint8 *result);
|
|
extern void scram_ClientKey(const uint8 *salted_password, uint8 *result);
|
|
extern void scram_ServerKey(const uint8 *salted_password, uint8 *result);
|
|
|
|
extern char *scram_build_verifier(const char *salt, int saltlen, int iterations,
|
|
const char *password);
|
|
|
|
#endif /* SCRAM_COMMON_H */
|