Files
quic-go/handshake/crypto_setup_client_test.go
2017-01-14 18:51:19 +07:00

121 lines
3.7 KiB
Go

package handshake
import (
"bytes"
"encoding/binary"
"time"
"github.com/lucas-clemente/quic-go/protocol"
"github.com/lucas-clemente/quic-go/qerr"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
var _ = Describe("Crypto setup", func() {
var cs *cryptoSetupClient
var stream *mockStream
BeforeEach(func() {
stream = &mockStream{}
csInt, err := NewCryptoSetupClient(0, protocol.Version36, stream)
Expect(err).ToNot(HaveOccurred())
cs = csInt.(*cryptoSetupClient)
})
Context("Reading SHLOs", func() {
var tagMap map[Tag][]byte
BeforeEach(func() {
tagMap = make(map[Tag][]byte)
})
It("rejects handshake messages with the wrong message tag", func() {
WriteHandshakeMessage(&stream.dataToRead, TagCHLO, tagMap)
err := cs.HandleCryptoStream()
Expect(err).To(MatchError(qerr.InvalidCryptoMessageType))
})
It("errors on invalid hanshake messages", func() {
b := &bytes.Buffer{}
WriteHandshakeMessage(b, TagCHLO, tagMap)
stream.dataToRead.Write(b.Bytes()[:b.Len()-2]) // cut the handshake message
err := cs.HandleCryptoStream()
// note that if this was a complete handshake message, HandleCryptoStream would fail with a qerr.InvalidCryptoMessageType
Expect(err).To(MatchError(qerr.HandshakeFailed))
})
})
Context("CHLO generation", func() {
It("is longer than the miminum client hello size", func() {
err := cs.sendCHLO()
Expect(err).ToNot(HaveOccurred())
Expect(cs.cryptoStream.(*mockStream).dataWritten.Len()).To(BeNumerically(">", protocol.ClientHelloMinimumSize))
})
It("has the right values for an inchoate CHLO", func() {
tags := cs.getTags()
Expect(tags).To(HaveKey(TagSNI))
Expect(tags[TagPDMD]).To(Equal([]byte("X509")))
Expect(tags[TagVER]).To(Equal([]byte("Q036")))
})
})
Context("Diversification Nonces", func() {
It("sets a diversification nonce", func() {
nonce := []byte("foobar")
err := cs.SetDiversificationNonce(nonce)
Expect(err).ToNot(HaveOccurred())
Expect(cs.diversificationNonce).To(Equal(nonce))
})
It("doesn't do anything when called multiple times with the same nonce", func() {
nonce := []byte("foobar")
err := cs.SetDiversificationNonce(nonce)
Expect(err).ToNot(HaveOccurred())
err = cs.SetDiversificationNonce(nonce)
Expect(err).ToNot(HaveOccurred())
Expect(cs.diversificationNonce).To(Equal(nonce))
})
It("rejects a different diversification nonce", func() {
nonce1 := []byte("foobar")
nonce2 := []byte("raboof")
err := cs.SetDiversificationNonce(nonce1)
Expect(err).ToNot(HaveOccurred())
err = cs.SetDiversificationNonce(nonce2)
Expect(err).To(MatchError(errConflictingDiversificationNonces))
})
})
Context("Client Nonce generation", func() {
BeforeEach(func() {
cs.serverConfig = &serverConfigClient{}
cs.serverConfig.obit = []byte{0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8}
})
It("generates a client nonce", func() {
now := time.Now()
nonce, err := cs.generateClientNonce()
Expect(nonce).To(HaveLen(32))
Expect(err).ToNot(HaveOccurred())
Expect(time.Unix(int64(binary.BigEndian.Uint32(nonce[0:4])), 0)).To(BeTemporally("~", now, 1*time.Second))
Expect(nonce[4:12]).To(Equal(cs.serverConfig.obit))
})
It("uses random values for the last 20 bytes", func() {
nonce1, err := cs.generateClientNonce()
Expect(err).ToNot(HaveOccurred())
nonce2, err := cs.generateClientNonce()
Expect(err).ToNot(HaveOccurred())
Expect(nonce1[4:12]).To(Equal(nonce2[4:12]))
Expect(nonce1[12:]).ToNot(Equal(nonce2[12:]))
})
It("errors if no OBIT value is available", func() {
cs.serverConfig.obit = []byte{}
_, err := cs.generateClientNonce()
Expect(err).To(MatchError(errNoObitForClientNonce))
})
})
})