()
| 212 | } |
| 213 | |
| 214 | func (sc *scramClient) clientFirstMessage() []byte { |
| 215 | // The client-first-message is the GS2 header concatenated with the bare |
| 216 | // message (username + client nonce). The GS2 header communicates the |
| 217 | // client's channel binding capability to the server: |
| 218 | // |
| 219 | // "n,," - client is not using TLS (channel binding not possible) |
| 220 | // "y,," - client is using TLS but channel binding is not |
| 221 | // in use (e.g., server did not advertise SCRAM-SHA-256-PLUS |
| 222 | // or the server certificate hash was not obtainable) |
| 223 | // "p=tls-server-end-point,," - channel binding is active via SCRAM-SHA-256-PLUS |
| 224 | // |
| 225 | // See: |
| 226 | // https://www.rfc-editor.org/rfc/rfc5802#section-6 |
| 227 | // https://www.rfc-editor.org/rfc/rfc5929#section-4 |
| 228 | // https://www.postgresql.org/docs/current/sasl-authentication.html#SASL-SCRAM-SHA-256 |
| 229 | |
| 230 | sc.clientFirstMessageBare = fmt.Appendf(nil, "n=,r=%s", sc.clientNonce) |
| 231 | |
| 232 | switch { |
| 233 | case sc.authMechanism == scramSHA256PlusName: |
| 234 | sc.clientGS2Header = []byte("p=tls-server-end-point,,") |
| 235 | case sc.hasTLS: |
| 236 | sc.clientGS2Header = []byte("y,,") |
| 237 | default: |
| 238 | sc.clientGS2Header = []byte("n,,") |
| 239 | } |
| 240 | |
| 241 | return append(sc.clientGS2Header, sc.clientFirstMessageBare...) |
| 242 | } |
| 243 | |
| 244 | func (sc *scramClient) recvServerFirstMessage(serverFirstMessage []byte) error { |
| 245 | sc.serverFirstMessage = serverFirstMessage |
no outgoing calls