forked from quic-go/quic-go
@@ -248,8 +248,9 @@ func (h *CryptoSetup) handleCHLO(sni string, data []byte, cryptoData map[Tag][]b
|
||||
}
|
||||
|
||||
clientNonce := cryptoData[TagNONC]
|
||||
if len(clientNonce) != 32 {
|
||||
return nil, qerr.Error(qerr.InvalidCryptoMessageParameter, "invalid client nonce length")
|
||||
err = h.validateClientNonce(clientNonce)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
h.secureAEAD, err = h.keyDerivation(
|
||||
@@ -331,3 +332,13 @@ func (h *CryptoSetup) UnlockForSealing() {
|
||||
func (h *CryptoSetup) HandshakeComplete() bool {
|
||||
return h.receivedForwardSecurePacket
|
||||
}
|
||||
|
||||
func (h *CryptoSetup) validateClientNonce(nonce []byte) error {
|
||||
if len(nonce) != 32 {
|
||||
return qerr.Error(qerr.InvalidCryptoMessageParameter, "invalid client nonce length")
|
||||
}
|
||||
if !bytes.Equal(nonce[4:12], h.scfg.obit) {
|
||||
return qerr.Error(qerr.InvalidCryptoMessageParameter, "OBIT not matching")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -150,7 +150,6 @@ var _ = Describe("Crypto setup", func() {
|
||||
ip = net.ParseIP("1.2.3.4")
|
||||
validSTK, err = mockStkSource{}.NewToken(ip)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
nonce32 = make([]byte, 32)
|
||||
expectedInitialNonceLen = 32
|
||||
expectedFSNonceLen = 64
|
||||
aeadChanged = make(chan struct{}, 1)
|
||||
@@ -158,6 +157,8 @@ var _ = Describe("Crypto setup", func() {
|
||||
kex = &mockKEX{}
|
||||
signer = &mockSigner{}
|
||||
scfg, err = NewServerConfig(kex, signer)
|
||||
nonce32 = make([]byte, 32)
|
||||
copy(nonce32[4:12], scfg.obit) // set the OBIT value at the right position
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
scfg.stkSource = &mockStkSource{}
|
||||
v := protocol.SupportedVersions[len(protocol.SupportedVersions)-1]
|
||||
@@ -274,6 +275,19 @@ var _ = Describe("Crypto setup", func() {
|
||||
Expect(err).To(MatchError(qerr.Error(qerr.InvalidCryptoMessageParameter, "invalid client nonce length")))
|
||||
})
|
||||
|
||||
It("rejects client nonces that have the wrong OBIT value", func() {
|
||||
nonce := make([]byte, 32) // the OBIT value is nonce[4:12] and here just initialized to 0
|
||||
WriteHandshakeMessage(&stream.dataToRead, TagCHLO, map[Tag][]byte{
|
||||
TagSCID: scfg.ID,
|
||||
TagSNI: []byte("quic.clemente.io"),
|
||||
TagNONC: nonce,
|
||||
TagSTK: validSTK,
|
||||
TagPUBS: nil,
|
||||
})
|
||||
err := cs.HandleCryptoStream()
|
||||
Expect(err).To(MatchError(qerr.Error(qerr.InvalidCryptoMessageParameter, "OBIT not matching")))
|
||||
})
|
||||
|
||||
It("handles 0-RTT handshake", func() {
|
||||
WriteHandshakeMessage(&stream.dataToRead, TagCHLO, map[Tag][]byte{
|
||||
TagSCID: scfg.ID,
|
||||
|
||||
@@ -9,9 +9,10 @@ import (
|
||||
|
||||
// ServerConfig is a server config
|
||||
type ServerConfig struct {
|
||||
ID []byte
|
||||
obit []byte
|
||||
kex crypto.KeyExchange
|
||||
signer crypto.Signer
|
||||
ID []byte
|
||||
stkSource crypto.StkSource
|
||||
}
|
||||
|
||||
@@ -33,9 +34,10 @@ func NewServerConfig(kex crypto.KeyExchange, signer crypto.Signer) (*ServerConfi
|
||||
}
|
||||
|
||||
return &ServerConfig{
|
||||
ID: id,
|
||||
obit: []byte{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7},
|
||||
kex: kex,
|
||||
signer: signer,
|
||||
ID: id,
|
||||
stkSource: stkSource,
|
||||
}, nil
|
||||
}
|
||||
@@ -48,7 +50,7 @@ func (s *ServerConfig) Get() []byte {
|
||||
TagKEXS: []byte("C255"),
|
||||
TagAEAD: []byte("AESG"),
|
||||
TagPUBS: append([]byte{0x20, 0x00, 0x00}, s.kex.PublicKey()...),
|
||||
TagOBIT: {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7},
|
||||
TagOBIT: s.obit,
|
||||
TagEXPY: {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
||||
})
|
||||
return serverConfig.Bytes()
|
||||
|
||||
Reference in New Issue
Block a user