|
1 | 1 | package main |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "bytes" |
4 | 5 | "context" |
5 | 6 | "crypto/x509" |
6 | 7 | "encoding/base64" |
@@ -31,8 +32,9 @@ import ( |
31 | 32 | var ( |
32 | 33 | monitoringURL = flag.String("monitoring_url", "", "Log monitoring URL.") |
33 | 34 | leafIndex = flag.String("leaf_index", "", "The index of the leaf to fetch.") |
34 | | - origin = flag.String("origin", "", "Origin of the log, for checkpoints and the monitoring prefix.") |
35 | | - logPubKey = flag.String("log_public_key", "", "Public key for the log, base64 encoded.") |
| 35 | + origin = flag.String("origin", "", "Origin of the log, for checkpoints and the monitoring prefix. MUST be provided if verify=true.") |
| 36 | + logPubKey = flag.String("log_public_key", "", "Public key for the log, base64 encoded. MUST be provided if verify=true.") |
| 37 | + verify = flag.Bool("verify", true, "Whether or not to verify the leaf entry.") |
36 | 38 | ) |
37 | 39 |
|
38 | 40 | var ( |
@@ -62,6 +64,15 @@ func main() { |
62 | 64 | klog.Exitf("Invalid --monitoring_url %q: %v", *monitoringURL, err) |
63 | 65 | } |
64 | 66 |
|
| 67 | + if *verify { |
| 68 | + if *logPubKey == "" { |
| 69 | + klog.Exitf("log_public_key MUST be provided when verify=true") |
| 70 | + } |
| 71 | + if *origin == "" { |
| 72 | + klog.Exitf("origin MUST be provided when verify=true") |
| 73 | + } |
| 74 | + } |
| 75 | + |
65 | 76 | // Create client |
66 | 77 | hc := &http.Client{ |
67 | 78 | Timeout: 30 * time.Second, |
@@ -96,8 +107,10 @@ func main() { |
96 | 107 | klog.Exitf("Failed to unmarshal entry: %v", err) |
97 | 108 | } |
98 | 109 |
|
99 | | - if errs := verify(ctx, &entry, cp, li, fetcher); len(errs) != 0 { |
100 | | - klog.Exitf("Failed to verify leaf entry: %s", errors.Join(errs...)) |
| 110 | + if *verify { |
| 111 | + if errs := verifyLeafEntry(ctx, &entry, cp, li, fetcher); len(errs) != 0 { |
| 112 | + klog.Exitf("Failed to verify leaf entry: %s", errors.Join(errs...)) |
| 113 | + } |
101 | 114 | } |
102 | 115 |
|
103 | 116 | pemBlock := &pem.Block{ |
@@ -152,18 +165,30 @@ func readCheckpoint(ctx context.Context, fetcher *client.HTTPFetcher) (*log.Chec |
152 | 165 | if err != nil { |
153 | 166 | return nil, fmt.Errorf("Failed to fetch checkpoint: %v", err) |
154 | 167 | } |
155 | | - logSigV, err := logSigVerifier(*origin, *logPubKey) |
156 | | - if err != nil { |
157 | | - return nil, fmt.Errorf("Failed to create verifier: %v", err) |
| 168 | + if *verify { |
| 169 | + logSigV, err := logSigVerifier(*origin, *logPubKey) |
| 170 | + if err != nil { |
| 171 | + return nil, fmt.Errorf("Failed to create verifier: %v", err) |
| 172 | + } |
| 173 | + cp, _, _, err := log.ParseCheckpoint(cpRaw, *origin, logSigV) |
| 174 | + if err != nil { |
| 175 | + return nil, fmt.Errorf("Failed to parse checkpoint: %v", err) |
| 176 | + } |
| 177 | + return cp, nil |
| 178 | + } |
| 179 | + // A https://c2sp.org/static-ct-api logsize is on the second line |
| 180 | + l := bytes.SplitN(cpRaw, []byte("\n"), 3) |
| 181 | + if len(l) < 2 { |
| 182 | + return nil, errors.New("invalid checkpoint - no size") |
158 | 183 | } |
159 | | - cp, _, _, err := log.ParseCheckpoint(cpRaw, *origin, logSigV) |
| 184 | + size, err := strconv.ParseUint(string(l[1]), 10, 64) |
160 | 185 | if err != nil { |
161 | | - return nil, fmt.Errorf("Failed to parse checkpoint: %v", err) |
| 186 | + return nil, fmt.Errorf("invalid checkpoint - can't extract size: %v", err) |
162 | 187 | } |
163 | | - return cp, nil |
| 188 | + return &log.Checkpoint{Size: size}, nil |
164 | 189 | } |
165 | 190 |
|
166 | | -func verify(ctx context.Context, entry *staticct.Entry, cp *log.Checkpoint, li uint64, fetcher *client.HTTPFetcher) []error { |
| 191 | +func verifyLeafEntry(ctx context.Context, entry *staticct.Entry, cp *log.Checkpoint, li uint64, fetcher *client.HTTPFetcher) []error { |
167 | 192 | // Check that the entry has been built properly |
168 | 193 | var errs []error |
169 | 194 | e := ctonly.Entry{ |
|
0 commit comments