implement certificate decompression, without cached and common certs

This commit is contained in:
Marten Seemann
2016-11-09 15:12:53 +07:00
parent 674287a8f4
commit 060d02cb4f
2 changed files with 97 additions and 0 deletions

View File

@@ -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:

View File

@@ -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)