forked from quic-go/quic-go
send common certificate sets in the client hello
This commit is contained in:
@@ -254,6 +254,16 @@ func splitHashes(hashes []byte) ([]uint64, error) {
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func getCommonCertificateHashes() []byte {
|
||||
ccs := make([]byte, 8*len(certSets), 8*len(certSets))
|
||||
i := 0
|
||||
for certSetHash := range certSets {
|
||||
binary.LittleEndian.PutUint64(ccs[i*8:(i+1)*8], certSetHash)
|
||||
i++
|
||||
}
|
||||
return ccs
|
||||
}
|
||||
|
||||
// HashCert calculates the FNV1a hash of a certificate
|
||||
func HashCert(cert []byte) uint64 {
|
||||
h := fnv.New64a()
|
||||
|
||||
@@ -272,4 +272,23 @@ var _ = Describe("Cert compression and decompression", func() {
|
||||
_, err = compressChain(chain, nil, []byte("foo"))
|
||||
Expect(err).To(MatchError("expected a multiple of 8 bytes for CCS / CCRT hashes"))
|
||||
})
|
||||
|
||||
Context("common certificate hashes", func() {
|
||||
It("gets the hashes", func() {
|
||||
ccs := getCommonCertificateHashes()
|
||||
Expect(ccs).ToNot(BeEmpty())
|
||||
hashes, err := splitHashes(ccs)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
for _, hash := range hashes {
|
||||
Expect(certSets).To(HaveKey(hash))
|
||||
}
|
||||
})
|
||||
|
||||
It("returns an empty slice if there are not common sets", func() {
|
||||
certSets = make(map[uint64]certSet)
|
||||
ccs := getCommonCertificateHashes()
|
||||
Expect(ccs).ToNot(BeNil())
|
||||
Expect(ccs).To(HaveLen(0))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
// CertManager manages the certificates sent by the server
|
||||
type CertManager interface {
|
||||
SetData([]byte) error
|
||||
GetCommonCertificateHashes() []byte
|
||||
GetLeafCert() []byte
|
||||
GetLeafCertHash() (uint64, error)
|
||||
VerifyServerProof(proof, chlo, serverConfigData []byte) bool
|
||||
@@ -50,6 +51,10 @@ func (c *certManager) SetData(data []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *certManager) GetCommonCertificateHashes() []byte {
|
||||
return getCommonCertificateHashes()
|
||||
}
|
||||
|
||||
// GetLeafCert returns the leaf certificate of the certificate chain
|
||||
// it returns nil if the certificate chain has not yet been set
|
||||
func (c *certManager) GetLeafCert() []byte {
|
||||
|
||||
@@ -42,6 +42,11 @@ var _ = Describe("Cert Manager", func() {
|
||||
Expect(err).To(MatchError(qerr.Error(qerr.InvalidCryptoMessageParameter, "Certificate data invalid")))
|
||||
})
|
||||
|
||||
It("gets the common certificate hashes", func() {
|
||||
ccs := cm.GetCommonCertificateHashes()
|
||||
Expect(ccs).ToNot(BeEmpty())
|
||||
})
|
||||
|
||||
Context("setting the data", func() {
|
||||
It("decompresses a certificate chain", func() {
|
||||
chain := [][]byte{cert1, cert2}
|
||||
|
||||
@@ -297,6 +297,11 @@ func (h *cryptoSetupClient) getTags() (map[Tag][]byte, error) {
|
||||
tags[TagSNI] = []byte(h.hostname)
|
||||
tags[TagPDMD] = []byte("X509")
|
||||
|
||||
ccs := h.certManager.GetCommonCertificateHashes()
|
||||
if len(ccs) > 0 {
|
||||
tags[TagCCS] = ccs
|
||||
}
|
||||
|
||||
versionTag := make([]byte, 4, 4)
|
||||
binary.LittleEndian.PutUint32(versionTag, protocol.VersionNumberToTag(h.version))
|
||||
tags[TagVER] = versionTag
|
||||
|
||||
@@ -44,6 +44,8 @@ type mockCertManager struct {
|
||||
setDataCalledWith []byte
|
||||
setDataError error
|
||||
|
||||
commonCertificateHashes []byte
|
||||
|
||||
leafCert []byte
|
||||
leafCertHash uint64
|
||||
leafCertHashError error
|
||||
@@ -60,6 +62,10 @@ func (m *mockCertManager) SetData(data []byte) error {
|
||||
return m.setDataError
|
||||
}
|
||||
|
||||
func (m *mockCertManager) GetCommonCertificateHashes() []byte {
|
||||
return m.commonCertificateHashes
|
||||
}
|
||||
|
||||
func (m *mockCertManager) GetLeafCert() []byte {
|
||||
return m.leafCert
|
||||
}
|
||||
@@ -361,11 +367,20 @@ var _ = Describe("Crypto setup", func() {
|
||||
|
||||
It("has the right values for an inchoate CHLO", func() {
|
||||
cs.hostname = "sni-hostname"
|
||||
certManager.commonCertificateHashes = []byte("common certs")
|
||||
tags, err := cs.getTags()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(string(tags[TagSNI])).To(Equal(cs.hostname))
|
||||
Expect(tags[TagPDMD]).To(Equal([]byte("X509")))
|
||||
Expect(tags[TagVER]).To(Equal([]byte("Q036")))
|
||||
Expect(tags[TagCCS]).To(Equal(certManager.commonCertificateHashes))
|
||||
})
|
||||
|
||||
It("doesn't send a CCS if there are no common certificate sets available", func() {
|
||||
certManager.commonCertificateHashes = nil
|
||||
tags, err := cs.getTags()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(tags).ToNot(HaveKey(TagCCS))
|
||||
})
|
||||
|
||||
It("includes the server config id, if available", func() {
|
||||
|
||||
Reference in New Issue
Block a user