forked from quic-go/quic-go
don’t send more than 3 CHLOs
makes sure that the server allows the client to make progress in the handshake
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
|||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -32,10 +33,11 @@ type cryptoSetupClient struct {
|
|||||||
lastSentCHLO []byte
|
lastSentCHLO []byte
|
||||||
certManager crypto.CertManager
|
certManager crypto.CertManager
|
||||||
|
|
||||||
serverVerified bool // has the certificate chain and the proof already been verified
|
clientHelloCounter int
|
||||||
keyDerivation KeyDerivationFunction
|
serverVerified bool // has the certificate chain and the proof already been verified
|
||||||
secureAEAD crypto.AEAD
|
keyDerivation KeyDerivationFunction
|
||||||
forwardSecureAEAD crypto.AEAD
|
secureAEAD crypto.AEAD
|
||||||
|
forwardSecureAEAD crypto.AEAD
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ crypto.AEAD = &cryptoSetupClient{}
|
var _ crypto.AEAD = &cryptoSetupClient{}
|
||||||
@@ -72,9 +74,12 @@ func (h *cryptoSetupClient) HandleCryptoStream() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = h.sendCHLO()
|
// send CHLOs until the forward secure encryption is established
|
||||||
if err != nil {
|
if h.forwardSecureAEAD == nil {
|
||||||
return err
|
err = h.sendCHLO()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var shloData bytes.Buffer
|
var shloData bytes.Buffer
|
||||||
@@ -260,6 +265,11 @@ func (h *cryptoSetupClient) HandshakeComplete() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *cryptoSetupClient) sendCHLO() error {
|
func (h *cryptoSetupClient) sendCHLO() error {
|
||||||
|
h.clientHelloCounter++
|
||||||
|
if h.clientHelloCounter > protocol.MaxClientHellos {
|
||||||
|
return qerr.Error(qerr.CryptoTooManyRejects, fmt.Sprintf("More than %d rejects", protocol.MaxClientHellos))
|
||||||
|
}
|
||||||
|
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
|
|
||||||
tags := h.getTags()
|
tags := h.getTags()
|
||||||
|
|||||||
@@ -403,6 +403,17 @@ var _ = Describe("Crypto setup", func() {
|
|||||||
Expect(tags[TagNONC]).To(Equal(cs.nonc))
|
Expect(tags[TagNONC]).To(Equal(cs.nonc))
|
||||||
Expect(tags[TagPUBS]).To(Equal(kex.PublicKey()))
|
Expect(tags[TagPUBS]).To(Equal(kex.PublicKey()))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("doesn't send more than MaxClientHellos CHLOs", func() {
|
||||||
|
Expect(cs.clientHelloCounter).To(BeZero())
|
||||||
|
for i := 1; i <= protocol.MaxClientHellos; i++ {
|
||||||
|
err := cs.sendCHLO()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(cs.clientHelloCounter).To(Equal(i))
|
||||||
|
}
|
||||||
|
err := cs.sendCHLO()
|
||||||
|
Expect(err).To(MatchError(qerr.Error(qerr.CryptoTooManyRejects, fmt.Sprintf("More than %d rejects", protocol.MaxClientHellos))))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("escalating crypto", func() {
|
Context("escalating crypto", func() {
|
||||||
|
|||||||
@@ -64,3 +64,9 @@ const MaxRetransmissionTime = 60 * time.Second
|
|||||||
|
|
||||||
// ClientHelloMinimumSize is the minimum size the server expects an inchoate CHLO to have.
|
// ClientHelloMinimumSize is the minimum size the server expects an inchoate CHLO to have.
|
||||||
const ClientHelloMinimumSize = 1024
|
const ClientHelloMinimumSize = 1024
|
||||||
|
|
||||||
|
// MaxClientHellos is the maximum number of times we'll send a client hello
|
||||||
|
// The value 3 accounts for:
|
||||||
|
// * one failure due to an incorrect or missing source-address token
|
||||||
|
// * one failure due the server's certificate chain being unavailible and the server being unwilling to send it without a valid source-address token
|
||||||
|
const MaxClientHellos = 3
|
||||||
|
|||||||
Reference in New Issue
Block a user