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
|
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 {
|
func buildEntries(chain [][]byte, chainHashes, cachedHashes, setHashes []uint64) []entry {
|
||||||
res := make([]entry, len(chain))
|
res := make([]entry, len(chain))
|
||||||
chainLoop:
|
chainLoop:
|
||||||
|
|||||||
@@ -28,6 +28,14 @@ var _ = Describe("Cert compression", func() {
|
|||||||
Expect(compressed).To(Equal([]byte{0}))
|
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() {
|
It("gives correct single cert", func() {
|
||||||
cert := []byte{0xde, 0xca, 0xfb, 0xad}
|
cert := []byte{0xde, 0xca, 0xfb, 0xad}
|
||||||
certZlib := &bytes.Buffer{}
|
certZlib := &bytes.Buffer{}
|
||||||
@@ -45,6 +53,16 @@ var _ = Describe("Cert compression", func() {
|
|||||||
}, certZlib.Bytes()...)))
|
}, 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() {
|
It("gives correct cert and intermediate", func() {
|
||||||
cert1 := []byte{0xde, 0xca, 0xfb, 0xad}
|
cert1 := []byte{0xde, 0xca, 0xfb, 0xad}
|
||||||
cert2 := []byte{0xde, 0xad, 0xbe, 0xef}
|
cert2 := []byte{0xde, 0xad, 0xbe, 0xef}
|
||||||
@@ -65,6 +83,17 @@ var _ = Describe("Cert compression", func() {
|
|||||||
}, certZlib.Bytes()...)))
|
}, 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() {
|
It("uses cached certificates", func() {
|
||||||
cert := []byte{0xde, 0xca, 0xfb, 0xad}
|
cert := []byte{0xde, 0xca, 0xfb, 0xad}
|
||||||
certHash := byteHash(cert)
|
certHash := byteHash(cert)
|
||||||
|
|||||||
Reference in New Issue
Block a user