Skip to content

Commit 15a1309

Browse files
committed
Add SCRAM-SHA-256-PLUS support
Extend the existing `SCRAM-SHA-256` authentication to support `SCRAM-SHA-256-PLUS` with tls-server-end-point channel binding (RFC 5929). `SCRAM-SHA-256` authenticates the client to the server but does not bind the authentication exchange to the underlying TLS connection. `SCRAM-SHA-256-PLUS` closes this gap by incorporating the server's TLS certificate hash into the SCRAM proof, ensuring that the authentication occurred over the same TLS session and protecting against man-in-the-middle attacks. When using SCRAM and the connection is over TLS and the server advertises `SCRAM-SHA-256-PLUS`, the client automatically upgrades. This behavior is controlled by adding support for the libpq `channel_binding` connection parameter. The `channel_binding` connection parameter supports the following values: - `prefer` (default): use `SCRAM-SHA-256-PLUS` when available. - `require`: fail if channel binding cannot be established. - `disable`: always use `SCRAM-SHA-256`. Resolves #2486.
1 parent 9a77b2b commit 15a1309

File tree

9 files changed

+747
-35
lines changed

9 files changed

+747
-35
lines changed

.devcontainer/docker-compose.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@ services:
2929
PGX_TEST_UNIX_SOCKET_CONN_STRING: "host=/var/run/postgresql port=5432 user=postgres dbname=pgx_test"
3030
PGX_TEST_TCP_CONN_STRING: "host=127.0.0.1 port=5432 user=pgx_md5 password=secret dbname=pgx_test"
3131
PGX_TEST_MD5_PASSWORD_CONN_STRING: "host=127.0.0.1 port=5432 user=pgx_md5 password=secret dbname=pgx_test"
32-
PGX_TEST_SCRAM_PASSWORD_CONN_STRING: "host=127.0.0.1 port=5432 user=pgx_scram password=secret dbname=pgx_test"
32+
PGX_TEST_SCRAM_PASSWORD_CONN_STRING: "host=localhost port=5432 user=pgx_scram password=secret dbname=pgx_test channel_binding=disable"
33+
PGX_TEST_SCRAM_PLUS_CONN_STRING: "host=127.0.0.1 port=5432 user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test channel_binding=require"
3334
PGX_TEST_PLAIN_PASSWORD_CONN_STRING: "host=127.0.0.1 port=5432 user=pgx_pw password=secret dbname=pgx_test"
34-
PGX_TEST_TLS_CONN_STRING: "host=localhost port=5432 user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test"
35+
PGX_TEST_TLS_CONN_STRING: "host=localhost port=5432 user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test channel_binding=disable"
3536
PGX_TEST_TLS_CLIENT_CONN_STRING: "host=localhost port=5432 user=pgx_sslcert sslmode=verify-full sslrootcert=/tmp/ca.pem sslcert=/tmp/pgx_sslcert.crt sslkey=/tmp/pgx_sslcert.key dbname=pgx_test"
3637
PGX_SSL_PASSWORD: certpw
3738

.github/workflows/ci.yml

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,50 +20,55 @@ jobs:
2020
pgx-test-database: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
2121
pgx-test-unix-socket-conn-string: "host=/var/run/postgresql dbname=pgx_test"
2222
pgx-test-tcp-conn-string: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
23-
pgx-test-scram-password-conn-string: "host=127.0.0.1 user=pgx_scram password=secret dbname=pgx_test"
23+
pgx-test-scram-password-conn-string: "host=127.0.0.1 user=pgx_scram password=secret dbname=pgx_test channel_binding=disable"
24+
pgx-test-scram-plus-conn-string: "host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test channel_binding=require"
2425
pgx-test-md5-password-conn-string: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
2526
pgx-test-plain-password-conn-string: "host=127.0.0.1 user=pgx_pw password=secret dbname=pgx_test"
26-
pgx-test-tls-conn-string: "host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test"
27+
pgx-test-tls-conn-string: "host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test channel_binding=disable"
2728
pgx-ssl-password: certpw
2829
pgx-test-tls-client-conn-string: "host=localhost user=pgx_sslcert sslmode=verify-full sslrootcert=/tmp/ca.pem sslcert=/tmp/pgx_sslcert.crt sslkey=/tmp/pgx_sslcert.key dbname=pgx_test"
2930
- pg-version: 15
3031
pgx-test-database: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
3132
pgx-test-unix-socket-conn-string: "host=/var/run/postgresql dbname=pgx_test"
3233
pgx-test-tcp-conn-string: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
33-
pgx-test-scram-password-conn-string: "host=127.0.0.1 user=pgx_scram password=secret dbname=pgx_test"
34+
pgx-test-scram-password-conn-string: "host=127.0.0.1 user=pgx_scram password=secret dbname=pgx_test channel_binding=disable"
35+
pgx-test-scram-plus-conn-string: "host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test channel_binding=require"
3436
pgx-test-md5-password-conn-string: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
3537
pgx-test-plain-password-conn-string: "host=127.0.0.1 user=pgx_pw password=secret dbname=pgx_test"
36-
pgx-test-tls-conn-string: "host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test"
38+
pgx-test-tls-conn-string: "host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test channel_binding=disable"
3739
pgx-ssl-password: certpw
3840
pgx-test-tls-client-conn-string: "host=localhost user=pgx_sslcert sslmode=verify-full sslrootcert=/tmp/ca.pem sslcert=/tmp/pgx_sslcert.crt sslkey=/tmp/pgx_sslcert.key dbname=pgx_test"
3941
- pg-version: 16
4042
pgx-test-database: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
4143
pgx-test-unix-socket-conn-string: "host=/var/run/postgresql dbname=pgx_test"
4244
pgx-test-tcp-conn-string: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
43-
pgx-test-scram-password-conn-string: "host=127.0.0.1 user=pgx_scram password=secret dbname=pgx_test"
45+
pgx-test-scram-password-conn-string: "host=127.0.0.1 user=pgx_scram password=secret dbname=pgx_test channel_binding=disable"
46+
pgx-test-scram-plus-conn-string: "host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test channel_binding=require"
4447
pgx-test-md5-password-conn-string: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
4548
pgx-test-plain-password-conn-string: "host=127.0.0.1 user=pgx_pw password=secret dbname=pgx_test"
46-
pgx-test-tls-conn-string: "host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test"
49+
pgx-test-tls-conn-string: "host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test channel_binding=disable"
4750
pgx-ssl-password: certpw
4851
pgx-test-tls-client-conn-string: "host=localhost user=pgx_sslcert sslmode=verify-full sslrootcert=/tmp/ca.pem sslcert=/tmp/pgx_sslcert.crt sslkey=/tmp/pgx_sslcert.key dbname=pgx_test"
4952
- pg-version: 17
5053
pgx-test-database: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
5154
pgx-test-unix-socket-conn-string: "host=/var/run/postgresql dbname=pgx_test"
5255
pgx-test-tcp-conn-string: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
53-
pgx-test-scram-password-conn-string: "host=127.0.0.1 user=pgx_scram password=secret dbname=pgx_test"
56+
pgx-test-scram-password-conn-string: "host=127.0.0.1 user=pgx_scram password=secret dbname=pgx_test channel_binding=disable"
57+
pgx-test-scram-plus-conn-string: "host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test channel_binding=require"
5458
pgx-test-md5-password-conn-string: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
5559
pgx-test-plain-password-conn-string: "host=127.0.0.1 user=pgx_pw password=secret dbname=pgx_test"
56-
pgx-test-tls-conn-string: "host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test"
60+
pgx-test-tls-conn-string: "host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test channel_binding=disable"
5761
pgx-ssl-password: certpw
5862
pgx-test-tls-client-conn-string: "host=localhost user=pgx_sslcert sslmode=verify-full sslrootcert=/tmp/ca.pem sslcert=/tmp/pgx_sslcert.crt sslkey=/tmp/pgx_sslcert.key dbname=pgx_test"
5963
- pg-version: 18
6064
pgx-test-database: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
6165
pgx-test-unix-socket-conn-string: "host=/var/run/postgresql dbname=pgx_test"
6266
pgx-test-tcp-conn-string: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
63-
pgx-test-scram-password-conn-string: "host=127.0.0.1 user=pgx_scram password=secret dbname=pgx_test"
67+
pgx-test-scram-password-conn-string: "host=127.0.0.1 user=pgx_scram password=secret dbname=pgx_test channel_binding=disable"
68+
pgx-test-scram-plus-conn-string: "host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test channel_binding=require"
6469
pgx-test-md5-password-conn-string: "host=127.0.0.1 user=pgx_md5 password=secret dbname=pgx_test"
6570
pgx-test-plain-password-conn-string: "host=127.0.0.1 user=pgx_pw password=secret dbname=pgx_test"
66-
pgx-test-tls-conn-string: "host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test"
71+
pgx-test-tls-conn-string: "host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=/tmp/ca.pem dbname=pgx_test channel_binding=disable"
6772
pgx-test-oauth: "true"
6873
pgx-ssl-password: certpw
6974
pgx-test-tls-client-conn-string: "host=localhost user=pgx_sslcert sslmode=verify-full sslrootcert=/tmp/ca.pem sslcert=/tmp/pgx_sslcert.crt sslkey=/tmp/pgx_sslcert.key dbname=pgx_test"
@@ -119,6 +124,7 @@ jobs:
119124
PGX_TEST_OAUTH: ${{ matrix.pgx-test-oauth }}
120125
# TestConnectTLS fails. However, it succeeds if I connect to the CI server with upterm and run it. Give up on that test for now.
121126
# PGX_TEST_TLS_CONN_STRING: ${{ matrix.pgx-test-tls-conn-string }}
127+
# PGX_TEST_SCRAM_PLUS_CONN_STRING: ${{ matrix.pgx-test-scram-plus-conn-string }}
122128
PGX_SSL_PASSWORD: ${{ matrix.pgx-ssl-password }}
123129
PGX_TEST_TLS_CLIENT_CONN_STRING: ${{ matrix.pgx-test-tls-client-conn-string }}
124130

CONTRIBUTING.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,11 @@ export POSTGRESQL_DATA_DIR=postgresql
8080
export PGX_TEST_DATABASE="host=127.0.0.1 database=pgx_test user=pgx_md5 password=secret"
8181
export PGX_TEST_UNIX_SOCKET_CONN_STRING="host=/private/tmp database=pgx_test"
8282
export PGX_TEST_TCP_CONN_STRING="host=127.0.0.1 database=pgx_test user=pgx_md5 password=secret"
83-
export PGX_TEST_SCRAM_PASSWORD_CONN_STRING="host=127.0.0.1 user=pgx_scram password=secret database=pgx_test"
83+
export PGX_TEST_SCRAM_PASSWORD_CONN_STRING="host=127.0.0.1 user=pgx_scram password=secret database=pgx_test channel_binding=disable"
84+
export PGX_TEST_SCRAM_PLUS_CONN_STRING="host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=`pwd`/.testdb/ca.pem database=pgx_test channel_binding=require"
8485
export PGX_TEST_MD5_PASSWORD_CONN_STRING="host=127.0.0.1 database=pgx_test user=pgx_md5 password=secret"
8586
export PGX_TEST_PLAIN_PASSWORD_CONN_STRING="host=127.0.0.1 user=pgx_pw password=secret"
86-
export PGX_TEST_TLS_CONN_STRING="host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=`pwd`/.testdb/ca.pem"
87+
export PGX_TEST_TLS_CONN_STRING="host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=`pwd`/.testdb/ca.pem channel_binding=disable"
8788
export PGX_SSL_PASSWORD=certpw
8889
export PGX_TEST_TLS_CLIENT_CONN_STRING="host=localhost user=pgx_sslcert sslmode=verify-full sslrootcert=`pwd`/.testdb/ca.pem database=pgx_test sslcert=`pwd`/.testdb/pgx_sslcert.crt sslkey=`pwd`/.testdb/pgx_sslcert.key"
8990
```

pgconn/auth_scram.go

Lines changed: 128 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
// SCRAM-SHA-256 authentication
1+
// SCRAM-SHA-256 and SCRAM-SHA-256-PLUS authentication
22
//
33
// Resources:
44
// https://tools.ietf.org/html/rfc5802
5+
// https://tools.ietf.org/html/rfc5929
56
// https://tools.ietf.org/html/rfc8265
67
// https://www.postgresql.org/docs/current/sasl-authentication.html
78
//
@@ -18,17 +19,25 @@ import (
1819
"crypto/pbkdf2"
1920
"crypto/rand"
2021
"crypto/sha256"
22+
"crypto/sha512"
23+
"crypto/tls"
24+
"crypto/x509"
2125
"encoding/base64"
2226
"errors"
2327
"fmt"
28+
"hash"
2429
"slices"
2530
"strconv"
2631

2732
"github.com/jackc/pgx/v5/pgproto3"
2833
"golang.org/x/text/secure/precis"
2934
)
3035

31-
const clientNonceLen = 18
36+
const (
37+
clientNonceLen = 18
38+
scramSHA256Name = "SCRAM-SHA-256"
39+
scramSHA256PlusName = "SCRAM-SHA-256-PLUS"
40+
)
3241

3342
// Perform SCRAM authentication.
3443
func (c *PgConn) scramAuth(serverAuthMechanisms []string) error {
@@ -37,9 +46,34 @@ func (c *PgConn) scramAuth(serverAuthMechanisms []string) error {
3746
return err
3847
}
3948

49+
serverHasPlus := slices.Contains(sc.serverAuthMechanisms, scramSHA256PlusName)
50+
if c.config.ChannelBinding == "require" && !serverHasPlus {
51+
return errors.New("channel binding required but server does not support SCRAM-SHA-256-PLUS")
52+
}
53+
54+
// If we have a TLS connection and channel binding is not disabled, attempt to
55+
// extract the server certificate hash for tls-server-end-point channel binding.
56+
if tlsConn, ok := c.conn.(*tls.Conn); ok && c.config.ChannelBinding != "disable" {
57+
certHash, err := getTLSCertificateHash(tlsConn)
58+
if err != nil && c.config.ChannelBinding == "require" {
59+
return fmt.Errorf("channel binding required but failed to get server certificate hash: %w", err)
60+
}
61+
62+
// Upgrade to SCRAM-SHA-256-PLUS if we have binding data and the server supports it.
63+
if certHash != nil && serverHasPlus {
64+
sc.authMechanism = scramSHA256PlusName
65+
}
66+
67+
sc.channelBindingData = certHash
68+
}
69+
70+
if c.config.ChannelBinding == "require" && sc.channelBindingData == nil {
71+
return errors.New("channel binding required but channel binding data is not available")
72+
}
73+
4074
// Send client-first-message in a SASLInitialResponse
4175
saslInitialResponse := &pgproto3.SASLInitialResponse{
42-
AuthMechanism: "SCRAM-SHA-256",
76+
AuthMechanism: sc.authMechanism,
4377
Data: sc.clientFirstMessage(),
4478
}
4579
c.frontend.Send(saslInitialResponse)
@@ -111,7 +145,22 @@ type scramClient struct {
111145
password string
112146
clientNonce []byte
113147

148+
// authMechanism is the clients selected SASL mechanism. Must be either
149+
// SCRAM-SHA-256 (default) or SCRAM-SHA-256-PLUS.
150+
//
151+
// Upgraded to SCRAM-SHA-256-PLUS during authentication when channel binding
152+
// is not disabled, channel binding data is available (TLS connection
153+
// with an obtainable server certificate hash) and the server advertises
154+
// SCRAM-SHA-256-PLUS.
155+
authMechanism string
156+
157+
// channelBindingData is the hash of the server's TLS certificate, computed
158+
// per the tls-server-end-point channel binding type (RFC 5929). Used as
159+
// the binding input in SCRAM-SHA-256-PLUS. nil when not in use.
160+
channelBindingData []byte
161+
114162
clientFirstMessageBare []byte
163+
clientGS2Header []byte
115164

116165
serverFirstMessage []byte
117166
clientAndServerNonce []byte
@@ -125,11 +174,14 @@ type scramClient struct {
125174
func newScramClient(serverAuthMechanisms []string, password string) (*scramClient, error) {
126175
sc := &scramClient{
127176
serverAuthMechanisms: serverAuthMechanisms,
177+
authMechanism: scramSHA256Name,
128178
}
129179

130-
// Ensure server supports SCRAM-SHA-256
131-
hasScramSHA256 := slices.Contains(sc.serverAuthMechanisms, "SCRAM-SHA-256")
132-
if !hasScramSHA256 {
180+
// Ensure the server supports SCRAM-SHA-256. SCRAM-SHA-256-PLUS is the
181+
// channel binding variant and is only advertised when the server supports
182+
// SSL. PostgreSQL always advertises the base SCRAM-SHA-256 mechanism
183+
// regardless of SSL.
184+
if !slices.Contains(sc.serverAuthMechanisms, scramSHA256Name) {
133185
return nil, errors.New("server does not support SCRAM-SHA-256")
134186
}
135187

@@ -153,8 +205,31 @@ func newScramClient(serverAuthMechanisms []string, password string) (*scramClien
153205
}
154206

155207
func (sc *scramClient) clientFirstMessage() []byte {
208+
// The client-first-message is the GS2 header concatenated with the bare
209+
// message (username + client nonce). The GS2 header communicates the
210+
// client's channel binding capability to the server:
211+
//
212+
// "n,," - client does not support channel binding
213+
// "y,," - client supports channel binding, but the
214+
// server did not advertise SCRAM-SHA-256-PLUS
215+
// "p=tls-server-end-point,," - channel binding is active via SCRAM-SHA-256-PLUS
216+
//
217+
// See:
218+
// https://www.rfc-editor.org/rfc/rfc5802#section-6
219+
// https://www.rfc-editor.org/rfc/rfc5929#section-4
220+
// https://www.postgresql.org/docs/current/sasl-authentication.html#SASL-SCRAM-SHA-256
221+
156222
sc.clientFirstMessageBare = fmt.Appendf(nil, "n=,r=%s", sc.clientNonce)
157-
return fmt.Appendf(nil, "n,,%s", sc.clientFirstMessageBare)
223+
224+
if sc.authMechanism == scramSHA256PlusName {
225+
sc.clientGS2Header = []byte("p=tls-server-end-point,,")
226+
} else if sc.channelBindingData != nil {
227+
sc.clientGS2Header = []byte("y,,")
228+
} else {
229+
sc.clientGS2Header = []byte("n,,")
230+
}
231+
232+
return append(sc.clientGS2Header, sc.clientFirstMessageBare...)
158233
}
159234

160235
func (sc *scramClient) recvServerFirstMessage(serverFirstMessage []byte) error {
@@ -213,7 +288,19 @@ func (sc *scramClient) recvServerFirstMessage(serverFirstMessage []byte) error {
213288
}
214289

215290
func (sc *scramClient) clientFinalMessage() string {
216-
clientFinalMessageWithoutProof := fmt.Appendf(nil, "c=biws,r=%s", sc.clientAndServerNonce)
291+
// The c= attribute carries the base64-encoded channel binding input.
292+
//
293+
// Without channel binding this is just the GS2 header alone ("biws" for
294+
// "n,," or "eSws" for "y,,").
295+
//
296+
// With channel binding, this is the GS2 header with the channel binding data
297+
// (certificate hash) appended.
298+
channelBindInput := sc.clientGS2Header
299+
if sc.authMechanism == scramSHA256PlusName {
300+
channelBindInput = slices.Concat(sc.clientGS2Header, sc.channelBindingData)
301+
}
302+
channelBindingEncoded := base64.StdEncoding.EncodeToString(channelBindInput)
303+
clientFinalMessageWithoutProof := fmt.Appendf(nil, "c=%s,r=%s", channelBindingEncoded, sc.clientAndServerNonce)
217304

218305
var err error
219306
sc.saltedPassword, err = pbkdf2.Key(sha256.New, sc.password, sc.salt, sc.iterations, 32)
@@ -269,3 +356,36 @@ func computeServerSignature(saltedPassword, authMessage []byte) []byte {
269356
base64.StdEncoding.Encode(buf, serverSignature)
270357
return buf
271358
}
359+
360+
// Get the server certificate hash for SCRAM channel binding type
361+
// tls-server-end-point.
362+
func getTLSCertificateHash(conn *tls.Conn) ([]byte, error) {
363+
state := conn.ConnectionState()
364+
if len(state.PeerCertificates) == 0 {
365+
return nil, errors.New("no peer certificates for channel binding")
366+
}
367+
368+
cert := state.PeerCertificates[0]
369+
370+
// Per RFC 5929 section 4.1: If the certificate's signatureAlgorithm uses
371+
// MD5 or SHA-1, use SHA-256. Otherwise use the hash from the signature
372+
// algorithm.
373+
//
374+
// See: https://www.rfc-editor.org/rfc/rfc5929.html#section-4.1
375+
var h hash.Hash
376+
switch cert.SignatureAlgorithm {
377+
case x509.MD5WithRSA, x509.SHA1WithRSA, x509.ECDSAWithSHA1:
378+
h = sha256.New()
379+
case x509.SHA256WithRSA, x509.SHA256WithRSAPSS, x509.ECDSAWithSHA256:
380+
h = sha256.New()
381+
case x509.SHA384WithRSA, x509.SHA384WithRSAPSS, x509.ECDSAWithSHA384:
382+
h = sha512.New384()
383+
case x509.SHA512WithRSA, x509.SHA512WithRSAPSS, x509.ECDSAWithSHA512:
384+
h = sha512.New()
385+
default:
386+
return nil, fmt.Errorf("tls-server-end-point channel binding is undefined for certificate signature algorithm %v", cert.SignatureAlgorithm)
387+
}
388+
389+
h.Write(cert.Raw)
390+
return h.Sum(nil), nil
391+
}

0 commit comments

Comments
 (0)