Skip to content

Commit afe9c88

Browse files
authored
Move parser into staticct.go (#236)
* move extension parsing into staticctapi * move staticctapi.go to staticct.go * Address comments
1 parent fd34aba commit afe9c88

File tree

2 files changed

+46
-36
lines changed

2 files changed

+46
-36
lines changed

internal/hammer/loadtest/client.go

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ package loadtest
1717
import (
1818
"bytes"
1919
"context"
20-
"encoding/base64"
2120
"encoding/json"
2221
"errors"
2322
"fmt"
@@ -31,7 +30,7 @@ import (
3130

3231
"github.com/transparency-dev/static-ct/internal/client"
3332
"github.com/transparency-dev/static-ct/internal/types/rfc6962"
34-
"golang.org/x/crypto/cryptobyte"
33+
"github.com/transparency-dev/static-ct/internal/types/staticct"
3534
"k8s.io/klog/v2"
3635
)
3736

@@ -240,41 +239,9 @@ func parseAddChainResponse(body []byte) (uint64, uint64, error) {
240239
return 0, 0, fmt.Errorf("can't parse add-chain response: %v", err)
241240
}
242241

243-
extensionBytes, err := base64.StdEncoding.DecodeString(resp.Extensions)
242+
leafIdx, err := staticct.ParseCTExtensions(resp.Extensions)
244243
if err != nil {
245-
return 0, 0, fmt.Errorf("can't decode extensions: %v", err)
246-
}
247-
extensions := cryptobyte.String(extensionBytes)
248-
var extensionType uint8
249-
var extensionData cryptobyte.String
250-
var leafIdx int64
251-
if !extensions.ReadUint8(&extensionType) {
252-
return 0, 0, fmt.Errorf("can't read extension type")
253-
}
254-
if extensionType != 0 {
255-
return 0, 0, fmt.Errorf("wrong extension type %d, want 0", extensionType)
256-
}
257-
if !extensions.ReadUint16LengthPrefixed(&extensionData) {
258-
return 0, 0, fmt.Errorf("can't read extension data")
259-
}
260-
if !readUint40(&extensionData, &leafIdx) {
261-
return 0, 0, fmt.Errorf("can't read leaf index from extension")
262-
}
263-
if !extensionData.Empty() ||
264-
!extensions.Empty() {
265-
return 0, 0, fmt.Errorf("invalid data tile extensions: %v", resp.Extensions)
244+
return 0, 0, fmt.Errorf("can't parse extensions: %v", err)
266245
}
267246
return uint64(leafIdx), resp.Timestamp, nil
268247
}
269-
270-
// readUint40 decodes a big-endian, 40-bit value into out and advances over it.
271-
// It reports whether the read was successful.
272-
// Code is copied from https://github.com/FiloSottile/sunlight/blob/main/extensions.go.
273-
func readUint40(s *cryptobyte.String, out *int64) bool {
274-
var v []byte
275-
if !s.ReadBytes(&v, 5) {
276-
return false
277-
}
278-
*out = int64(v[0])<<32 | int64(v[1])<<24 | int64(v[2])<<16 | int64(v[3])<<8 | int64(v[4])
279-
return true
280-
}

internal/types/staticct/staticctapi.go renamed to internal/types/staticct/staticct.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package staticct
1616

1717
import (
18+
"encoding/base64"
1819
"fmt"
1920
"math"
2021

@@ -102,3 +103,45 @@ func (t *EntryBundle) UnmarshalText(raw []byte) error {
102103
t.Entries = entries
103104
return nil
104105
}
106+
107+
// parseCTExtensions parses CTExtensions into an index.
108+
// Code is inspired by https://github.com/FiloSottile/sunlight/blob/main/tile.go.
109+
func ParseCTExtensions(ext string) (uint64, error) {
110+
extensionBytes, err := base64.StdEncoding.DecodeString(ext)
111+
if err != nil {
112+
return 0, fmt.Errorf("can't decode extensions: %v", err)
113+
}
114+
extensions := cryptobyte.String(extensionBytes)
115+
var extensionType uint8
116+
var extensionData cryptobyte.String
117+
var leafIdx uint64
118+
if !extensions.ReadUint8(&extensionType) {
119+
return 0, fmt.Errorf("can't read extension type")
120+
}
121+
if extensionType != 0 {
122+
return 0, fmt.Errorf("wrong extension type %d, want 0", extensionType)
123+
}
124+
if !extensions.ReadUint16LengthPrefixed(&extensionData) {
125+
return 0, fmt.Errorf("can't read extension data")
126+
}
127+
if !readUint40(&extensionData, &leafIdx) {
128+
return 0, fmt.Errorf("can't read leaf index from extension")
129+
}
130+
if !extensionData.Empty() ||
131+
!extensions.Empty() {
132+
return 0, fmt.Errorf("invalid SCT extension data: %v", ext)
133+
}
134+
return leafIdx, nil
135+
}
136+
137+
// readUint40 decodes a big-endian, 40-bit value into out and advances over it.
138+
// It reports whether the read was successful.
139+
// Code is copied from https://github.com/FiloSottile/sunlight/blob/main/extensions.go.
140+
func readUint40(s *cryptobyte.String, out *uint64) bool {
141+
var v []byte
142+
if !s.ReadBytes(&v, 5) {
143+
return false
144+
}
145+
*out = uint64(v[0])<<32 | uint64(v[1])<<24 | uint64(v[2])<<16 | uint64(v[3])<<8 | uint64(v[4])
146+
return true
147+
}

0 commit comments

Comments
 (0)