Merge pull request #741 from cheat/dependabot/go_modules/golang.org/x/crypto-0.17.0

chore(deps): bump golang.org/x/crypto from 0.16.0 to 0.17.0
This commit is contained in:
Chris Allen Lane 2023-12-19 14:51:50 -05:00 committed by GitHub
commit 4bf804ac60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 116 additions and 58 deletions

2
go.mod
View File

@ -29,7 +29,7 @@ require (
github.com/sergi/go-diff v1.3.1 // indirect github.com/sergi/go-diff v1.3.1 // indirect
github.com/skeema/knownhosts v1.2.1 // indirect github.com/skeema/knownhosts v1.2.1 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect
golang.org/x/crypto v0.16.0 // indirect golang.org/x/crypto v0.17.0 // indirect
golang.org/x/mod v0.14.0 // indirect golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.19.0 // indirect golang.org/x/net v0.19.0 // indirect
golang.org/x/sys v0.15.0 // indirect golang.org/x/sys v0.15.0 // indirect

4
go.sum
View File

@ -77,8 +77,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=

View File

@ -199,8 +199,8 @@ TEXT ·mixBlocksSSE2(SB), 4, $0-32
MOVQ out+0(FP), DX MOVQ out+0(FP), DX
MOVQ a+8(FP), AX MOVQ a+8(FP), AX
MOVQ b+16(FP), BX MOVQ b+16(FP), BX
MOVQ a+24(FP), CX MOVQ c+24(FP), CX
MOVQ $128, BP MOVQ $128, DI
loop: loop:
MOVOU 0(AX), X0 MOVOU 0(AX), X0
@ -213,7 +213,7 @@ loop:
ADDQ $16, BX ADDQ $16, BX
ADDQ $16, CX ADDQ $16, CX
ADDQ $16, DX ADDQ $16, DX
SUBQ $2, BP SUBQ $2, DI
JA loop JA loop
RET RET
@ -222,8 +222,8 @@ TEXT ·xorBlocksSSE2(SB), 4, $0-32
MOVQ out+0(FP), DX MOVQ out+0(FP), DX
MOVQ a+8(FP), AX MOVQ a+8(FP), AX
MOVQ b+16(FP), BX MOVQ b+16(FP), BX
MOVQ a+24(FP), CX MOVQ c+24(FP), CX
MOVQ $128, BP MOVQ $128, DI
loop: loop:
MOVOU 0(AX), X0 MOVOU 0(AX), X0
@ -238,6 +238,6 @@ loop:
ADDQ $16, BX ADDQ $16, BX
ADDQ $16, CX ADDQ $16, CX
ADDQ $16, DX ADDQ $16, DX
SUBQ $2, BP SUBQ $2, DI
JA loop JA loop
RET RET

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build go1.7 && amd64 && gc && !purego //go:build amd64 && gc && !purego
package blake2b package blake2b

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build go1.7 && amd64 && gc && !purego //go:build amd64 && gc && !purego
#include "textflag.h" #include "textflag.h"

View File

@ -1,24 +0,0 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build !go1.7 && amd64 && gc && !purego
package blake2b
import "golang.org/x/sys/cpu"
func init() {
useSSE4 = cpu.X86.HasSSE41
}
//go:noescape
func hashBlocksSSE4(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
func hashBlocks(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {
if useSSE4 {
hashBlocksSSE4(h, c, flag, blocks)
} else {
hashBlocksGeneric(h, c, flag, blocks)
}
}

View File

@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build go1.9
package blake2b package blake2b
import ( import (

View File

@ -319,9 +319,9 @@
MOVQ rDi, _si(oState); \ MOVQ rDi, _si(oState); \
MOVQ rDo, _so(oState) \ MOVQ rDo, _so(oState) \
// func keccakF1600(state *[25]uint64) // func keccakF1600(a *[25]uint64)
TEXT ·keccakF1600(SB), 0, $200-8 TEXT ·keccakF1600(SB), 0, $200-8
MOVQ state+0(FP), rpState MOVQ a+0(FP), rpState
// Convert the user state into an internal state // Convert the user state into an internal state
NOTQ _be(rpState) NOTQ _be(rpState)

View File

@ -187,9 +187,11 @@ type channel struct {
pending *buffer pending *buffer
extPending *buffer extPending *buffer
// windowMu protects myWindow, the flow-control window. // windowMu protects myWindow, the flow-control window, and myConsumed,
// the number of bytes consumed since we last increased myWindow
windowMu sync.Mutex windowMu sync.Mutex
myWindow uint32 myWindow uint32
myConsumed uint32
// writeMu serializes calls to mux.conn.writePacket() and // writeMu serializes calls to mux.conn.writePacket() and
// protects sentClose and packetPool. This mutex must be // protects sentClose and packetPool. This mutex must be
@ -332,14 +334,24 @@ func (ch *channel) handleData(packet []byte) error {
return nil return nil
} }
func (c *channel) adjustWindow(n uint32) error { func (c *channel) adjustWindow(adj uint32) error {
c.windowMu.Lock() c.windowMu.Lock()
// Since myWindow is managed on our side, and can never exceed // Since myConsumed and myWindow are managed on our side, and can never
// the initial window setting, we don't worry about overflow. // exceed the initial window setting, we don't worry about overflow.
c.myWindow += uint32(n) c.myConsumed += adj
var sendAdj uint32
if (channelWindowSize-c.myWindow > 3*c.maxIncomingPayload) ||
(c.myWindow < channelWindowSize/2) {
sendAdj = c.myConsumed
c.myConsumed = 0
c.myWindow += sendAdj
}
c.windowMu.Unlock() c.windowMu.Unlock()
if sendAdj == 0 {
return nil
}
return c.sendMessage(windowAdjustMsg{ return c.sendMessage(windowAdjustMsg{
AdditionalBytes: uint32(n), AdditionalBytes: sendAdj,
}) })
} }

View File

@ -82,7 +82,7 @@ func NewClientConn(c net.Conn, addr string, config *ClientConfig) (Conn, <-chan
if err := conn.clientHandshake(addr, &fullConf); err != nil { if err := conn.clientHandshake(addr, &fullConf); err != nil {
c.Close() c.Close()
return nil, nil, nil, fmt.Errorf("ssh: handshake failed: %v", err) return nil, nil, nil, fmt.Errorf("ssh: handshake failed: %w", err)
} }
conn.mux = newMux(conn.transport) conn.mux = newMux(conn.transport)
return conn, conn.mux.incomingChannels, conn.mux.incomingRequests, nil return conn, conn.mux.incomingChannels, conn.mux.incomingRequests, nil

View File

@ -35,6 +35,16 @@ type keyingTransport interface {
// direction will be effected if a msgNewKeys message is sent // direction will be effected if a msgNewKeys message is sent
// or received. // or received.
prepareKeyChange(*algorithms, *kexResult) error prepareKeyChange(*algorithms, *kexResult) error
// setStrictMode sets the strict KEX mode, notably triggering
// sequence number resets on sending or receiving msgNewKeys.
// If the sequence number is already > 1 when setStrictMode
// is called, an error is returned.
setStrictMode() error
// setInitialKEXDone indicates to the transport that the initial key exchange
// was completed
setInitialKEXDone()
} }
// handshakeTransport implements rekeying on top of a keyingTransport // handshakeTransport implements rekeying on top of a keyingTransport
@ -100,6 +110,10 @@ type handshakeTransport struct {
// The session ID or nil if first kex did not complete yet. // The session ID or nil if first kex did not complete yet.
sessionID []byte sessionID []byte
// strictMode indicates if the other side of the handshake indicated
// that we should be following the strict KEX protocol restrictions.
strictMode bool
} }
type pendingKex struct { type pendingKex struct {
@ -209,7 +223,10 @@ func (t *handshakeTransport) readLoop() {
close(t.incoming) close(t.incoming)
break break
} }
if p[0] == msgIgnore || p[0] == msgDebug { // If this is the first kex, and strict KEX mode is enabled,
// we don't ignore any messages, as they may be used to manipulate
// the packet sequence numbers.
if !(t.sessionID == nil && t.strictMode) && (p[0] == msgIgnore || p[0] == msgDebug) {
continue continue
} }
t.incoming <- p t.incoming <- p
@ -441,6 +458,11 @@ func (t *handshakeTransport) readOnePacket(first bool) ([]byte, error) {
return successPacket, nil return successPacket, nil
} }
const (
kexStrictClient = "kex-strict-c-v00@openssh.com"
kexStrictServer = "kex-strict-s-v00@openssh.com"
)
// sendKexInit sends a key change message. // sendKexInit sends a key change message.
func (t *handshakeTransport) sendKexInit() error { func (t *handshakeTransport) sendKexInit() error {
t.mu.Lock() t.mu.Lock()
@ -454,7 +476,6 @@ func (t *handshakeTransport) sendKexInit() error {
} }
msg := &kexInitMsg{ msg := &kexInitMsg{
KexAlgos: t.config.KeyExchanges,
CiphersClientServer: t.config.Ciphers, CiphersClientServer: t.config.Ciphers,
CiphersServerClient: t.config.Ciphers, CiphersServerClient: t.config.Ciphers,
MACsClientServer: t.config.MACs, MACsClientServer: t.config.MACs,
@ -464,6 +485,13 @@ func (t *handshakeTransport) sendKexInit() error {
} }
io.ReadFull(rand.Reader, msg.Cookie[:]) io.ReadFull(rand.Reader, msg.Cookie[:])
// We mutate the KexAlgos slice, in order to add the kex-strict extension algorithm,
// and possibly to add the ext-info extension algorithm. Since the slice may be the
// user owned KeyExchanges, we create our own slice in order to avoid using user
// owned memory by mistake.
msg.KexAlgos = make([]string, 0, len(t.config.KeyExchanges)+2) // room for kex-strict and ext-info
msg.KexAlgos = append(msg.KexAlgos, t.config.KeyExchanges...)
isServer := len(t.hostKeys) > 0 isServer := len(t.hostKeys) > 0
if isServer { if isServer {
for _, k := range t.hostKeys { for _, k := range t.hostKeys {
@ -488,17 +516,24 @@ func (t *handshakeTransport) sendKexInit() error {
msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, keyFormat) msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, keyFormat)
} }
} }
if t.sessionID == nil {
msg.KexAlgos = append(msg.KexAlgos, kexStrictServer)
}
} else { } else {
msg.ServerHostKeyAlgos = t.hostKeyAlgorithms msg.ServerHostKeyAlgos = t.hostKeyAlgorithms
// As a client we opt in to receiving SSH_MSG_EXT_INFO so we know what // As a client we opt in to receiving SSH_MSG_EXT_INFO so we know what
// algorithms the server supports for public key authentication. See RFC // algorithms the server supports for public key authentication. See RFC
// 8308, Section 2.1. // 8308, Section 2.1.
//
// We also send the strict KEX mode extension algorithm, in order to opt
// into the strict KEX mode.
if firstKeyExchange := t.sessionID == nil; firstKeyExchange { if firstKeyExchange := t.sessionID == nil; firstKeyExchange {
msg.KexAlgos = make([]string, 0, len(t.config.KeyExchanges)+1)
msg.KexAlgos = append(msg.KexAlgos, t.config.KeyExchanges...)
msg.KexAlgos = append(msg.KexAlgos, "ext-info-c") msg.KexAlgos = append(msg.KexAlgos, "ext-info-c")
msg.KexAlgos = append(msg.KexAlgos, kexStrictClient)
} }
} }
packet := Marshal(msg) packet := Marshal(msg)
@ -604,6 +639,13 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
return err return err
} }
if t.sessionID == nil && ((isClient && contains(serverInit.KexAlgos, kexStrictServer)) || (!isClient && contains(clientInit.KexAlgos, kexStrictClient))) {
t.strictMode = true
if err := t.conn.setStrictMode(); err != nil {
return err
}
}
// We don't send FirstKexFollows, but we handle receiving it. // We don't send FirstKexFollows, but we handle receiving it.
// //
// RFC 4253 section 7 defines the kex and the agreement method for // RFC 4253 section 7 defines the kex and the agreement method for
@ -679,6 +721,12 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
return unexpectedMessageError(msgNewKeys, packet[0]) return unexpectedMessageError(msgNewKeys, packet[0])
} }
if firstKeyExchange {
// Indicates to the transport that the first key exchange is completed
// after receiving SSH_MSG_NEWKEYS.
t.conn.setInitialKEXDone()
}
return nil return nil
} }

View File

@ -213,6 +213,7 @@ func NewServerConn(c net.Conn, config *ServerConfig) (*ServerConn, <-chan NewCha
} else { } else {
for _, algo := range fullConf.PublicKeyAuthAlgorithms { for _, algo := range fullConf.PublicKeyAuthAlgorithms {
if !contains(supportedPubKeyAuthAlgos, algo) { if !contains(supportedPubKeyAuthAlgos, algo) {
c.Close()
return nil, nil, nil, fmt.Errorf("ssh: unsupported public key authentication algorithm %s", algo) return nil, nil, nil, fmt.Errorf("ssh: unsupported public key authentication algorithm %s", algo)
} }
} }
@ -220,6 +221,7 @@ func NewServerConn(c net.Conn, config *ServerConfig) (*ServerConn, <-chan NewCha
// Check if the config contains any unsupported key exchanges // Check if the config contains any unsupported key exchanges
for _, kex := range fullConf.KeyExchanges { for _, kex := range fullConf.KeyExchanges {
if _, ok := serverForbiddenKexAlgos[kex]; ok { if _, ok := serverForbiddenKexAlgos[kex]; ok {
c.Close()
return nil, nil, nil, fmt.Errorf("ssh: unsupported key exchange %s for server", kex) return nil, nil, nil, fmt.Errorf("ssh: unsupported key exchange %s for server", kex)
} }
} }

View File

@ -49,6 +49,9 @@ type transport struct {
rand io.Reader rand io.Reader
isClient bool isClient bool
io.Closer io.Closer
strictMode bool
initialKEXDone bool
} }
// packetCipher represents a combination of SSH encryption/MAC // packetCipher represents a combination of SSH encryption/MAC
@ -74,6 +77,18 @@ type connectionState struct {
pendingKeyChange chan packetCipher pendingKeyChange chan packetCipher
} }
func (t *transport) setStrictMode() error {
if t.reader.seqNum != 1 {
return errors.New("ssh: sequence number != 1 when strict KEX mode requested")
}
t.strictMode = true
return nil
}
func (t *transport) setInitialKEXDone() {
t.initialKEXDone = true
}
// prepareKeyChange sets up key material for a keychange. The key changes in // prepareKeyChange sets up key material for a keychange. The key changes in
// both directions are triggered by reading and writing a msgNewKey packet // both directions are triggered by reading and writing a msgNewKey packet
// respectively. // respectively.
@ -112,11 +127,12 @@ func (t *transport) printPacket(p []byte, write bool) {
// Read and decrypt next packet. // Read and decrypt next packet.
func (t *transport) readPacket() (p []byte, err error) { func (t *transport) readPacket() (p []byte, err error) {
for { for {
p, err = t.reader.readPacket(t.bufReader) p, err = t.reader.readPacket(t.bufReader, t.strictMode)
if err != nil { if err != nil {
break break
} }
if len(p) == 0 || (p[0] != msgIgnore && p[0] != msgDebug) { // in strict mode we pass through DEBUG and IGNORE packets only during the initial KEX
if len(p) == 0 || (t.strictMode && !t.initialKEXDone) || (p[0] != msgIgnore && p[0] != msgDebug) {
break break
} }
} }
@ -127,7 +143,7 @@ func (t *transport) readPacket() (p []byte, err error) {
return p, err return p, err
} }
func (s *connectionState) readPacket(r *bufio.Reader) ([]byte, error) { func (s *connectionState) readPacket(r *bufio.Reader, strictMode bool) ([]byte, error) {
packet, err := s.packetCipher.readCipherPacket(s.seqNum, r) packet, err := s.packetCipher.readCipherPacket(s.seqNum, r)
s.seqNum++ s.seqNum++
if err == nil && len(packet) == 0 { if err == nil && len(packet) == 0 {
@ -140,6 +156,9 @@ func (s *connectionState) readPacket(r *bufio.Reader) ([]byte, error) {
select { select {
case cipher := <-s.pendingKeyChange: case cipher := <-s.pendingKeyChange:
s.packetCipher = cipher s.packetCipher = cipher
if strictMode {
s.seqNum = 0
}
default: default:
return nil, errors.New("ssh: got bogus newkeys message") return nil, errors.New("ssh: got bogus newkeys message")
} }
@ -170,10 +189,10 @@ func (t *transport) writePacket(packet []byte) error {
if debugTransport { if debugTransport {
t.printPacket(packet, true) t.printPacket(packet, true)
} }
return t.writer.writePacket(t.bufWriter, t.rand, packet) return t.writer.writePacket(t.bufWriter, t.rand, packet, t.strictMode)
} }
func (s *connectionState) writePacket(w *bufio.Writer, rand io.Reader, packet []byte) error { func (s *connectionState) writePacket(w *bufio.Writer, rand io.Reader, packet []byte, strictMode bool) error {
changeKeys := len(packet) > 0 && packet[0] == msgNewKeys changeKeys := len(packet) > 0 && packet[0] == msgNewKeys
err := s.packetCipher.writeCipherPacket(s.seqNum, w, rand, packet) err := s.packetCipher.writeCipherPacket(s.seqNum, w, rand, packet)
@ -188,6 +207,9 @@ func (s *connectionState) writePacket(w *bufio.Writer, rand io.Reader, packet []
select { select {
case cipher := <-s.pendingKeyChange: case cipher := <-s.pendingKeyChange:
s.packetCipher = cipher s.packetCipher = cipher
if strictMode {
s.seqNum = 0
}
default: default:
panic("ssh: no key material for msgNewKeys") panic("ssh: no key material for msgNewKeys")
} }

2
vendor/modules.txt vendored
View File

@ -163,7 +163,7 @@ github.com/skeema/knownhosts
# github.com/xanzy/ssh-agent v0.3.3 # github.com/xanzy/ssh-agent v0.3.3
## explicit; go 1.16 ## explicit; go 1.16
github.com/xanzy/ssh-agent github.com/xanzy/ssh-agent
# golang.org/x/crypto v0.16.0 # golang.org/x/crypto v0.17.0
## explicit; go 1.18 ## explicit; go 1.18
golang.org/x/crypto/argon2 golang.org/x/crypto/argon2
golang.org/x/crypto/blake2b golang.org/x/crypto/blake2b