forked from quic-go/quic-go
implement certificate decompression, without cached and common certs
This commit is contained in:
@@ -89,6 +89,74 @@ func compressChain(chain [][]byte, pCommonSetHashes, pCachedHashes []byte) ([]by
|
||||
return res.Bytes(), nil
|
||||
}
|
||||
|
||||
func decompressChain(data []byte) ([][]byte, error) {
|
||||
var chain [][]byte
|
||||
r := bytes.NewReader(data)
|
||||
|
||||
var numCerts int
|
||||
for {
|
||||
entryTypeByte, err := r.ReadByte()
|
||||
if entryTypeByte == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
et := entryType(entryTypeByte)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
numCerts++
|
||||
|
||||
switch et {
|
||||
case entryCached:
|
||||
panic("not yet implemented")
|
||||
case entryCommon:
|
||||
panic("not yet implemented")
|
||||
case entryCompressed:
|
||||
continue
|
||||
default:
|
||||
return nil, errors.New("unknown entryType")
|
||||
}
|
||||
}
|
||||
|
||||
if numCerts == 0 {
|
||||
return make([][]byte, 0, 0), nil
|
||||
}
|
||||
|
||||
uncompressedLength, err := utils.ReadUint32(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
gz, err := zlib.NewReaderDict(r, certDictZlib)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer gz.Close()
|
||||
|
||||
var totalLength uint32
|
||||
for totalLength < uncompressedLength {
|
||||
lenBytes := make([]byte, 4)
|
||||
_, err := gz.Read(lenBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
certLen := binary.LittleEndian.Uint32(lenBytes)
|
||||
|
||||
cert := make([]byte, certLen)
|
||||
n, err := gz.Read(cert)
|
||||
if uint32(n) != certLen && err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
chain = append(chain, cert)
|
||||
|
||||
totalLength += 4 + certLen
|
||||
}
|
||||
|
||||
return chain, nil
|
||||
}
|
||||
|
||||
func buildEntries(chain [][]byte, chainHashes, cachedHashes, setHashes []uint64) []entry {
|
||||
res := make([]entry, len(chain))
|
||||
chainLoop:
|
||||
|
||||
@@ -28,6 +28,14 @@ var _ = Describe("Cert compression", func() {
|
||||
Expect(compressed).To(Equal([]byte{0}))
|
||||
})
|
||||
|
||||
It("decompresses empty", func() {
|
||||
compressed, err := compressChain(nil, nil, nil)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
uncompressed, err := decompressChain(compressed)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(uncompressed).To(BeEmpty())
|
||||
})
|
||||
|
||||
It("gives correct single cert", func() {
|
||||
cert := []byte{0xde, 0xca, 0xfb, 0xad}
|
||||
certZlib := &bytes.Buffer{}
|
||||
@@ -45,6 +53,16 @@ var _ = Describe("Cert compression", func() {
|
||||
}, certZlib.Bytes()...)))
|
||||
})
|
||||
|
||||
It("decompresses a single cert", func() {
|
||||
cert := []byte{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe}
|
||||
chain := [][]byte{cert}
|
||||
compressed, err := compressChain(chain, nil, nil)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
uncompressed, err := decompressChain(compressed)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(uncompressed).To(Equal(chain))
|
||||
})
|
||||
|
||||
It("gives correct cert and intermediate", func() {
|
||||
cert1 := []byte{0xde, 0xca, 0xfb, 0xad}
|
||||
cert2 := []byte{0xde, 0xad, 0xbe, 0xef}
|
||||
@@ -65,6 +83,17 @@ var _ = Describe("Cert compression", func() {
|
||||
}, certZlib.Bytes()...)))
|
||||
})
|
||||
|
||||
It("decompresses the chain with a cert and an intermediate", func() {
|
||||
cert1 := []byte{0xde, 0xca, 0xfb, 0xad}
|
||||
cert2 := []byte{0xde, 0xad, 0xbe, 0xef}
|
||||
chain := [][]byte{cert1, cert2}
|
||||
compressed, err := compressChain(chain, nil, nil)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
decompressed, err := decompressChain(compressed)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(decompressed).To(Equal(chain))
|
||||
})
|
||||
|
||||
It("uses cached certificates", func() {
|
||||
cert := []byte{0xde, 0xca, 0xfb, 0xad}
|
||||
certHash := byteHash(cert)
|
||||
|
||||
Reference in New Issue
Block a user