...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package cmd
16
17 import (
18 "context"
19 "fmt"
20 "sort"
21
22 ct "github.com/google/certificate-transparency-go"
23 "github.com/spf13/cobra"
24 "k8s.io/klog/v2"
25 )
26
27 func init() {
28 cmd := cobra.Command{
29 Use: fmt.Sprintf("bisect %s --timestamp=ts [--chain] [--text=false]", connectionFlags),
30 Aliases: []string{"find-timestamp"},
31 Short: "Find a log entry by timestamp",
32 Args: cobra.MaximumNArgs(0),
33 Run: func(cmd *cobra.Command, _ []string) {
34 runBisect(cmd.Context())
35 },
36 }
37 cmd.Flags().Int64Var(×tamp, "timestamp", 0, "Timestamp to use for inclusion checking")
38
39 cmd.Flags().BoolVar(&chainOut, "chain", false, "Display entire certificate chain")
40 cmd.Flags().BoolVar(&textOut, "text", true, "Display certificates as text")
41 rootCmd.AddCommand(&cmd)
42 }
43
44
45 func runBisect(ctx context.Context) {
46 logClient := connect(ctx)
47 if timestamp == 0 {
48 klog.Exit("No -timestamp option supplied")
49 }
50 target := timestamp
51 sth, err := logClient.GetSTH(ctx)
52 if err != nil {
53 exitWithDetails(err)
54 }
55 getEntry := func(idx int64) *ct.RawLogEntry {
56 entries, err := logClient.GetRawEntries(ctx, idx, idx)
57 if err != nil {
58 exitWithDetails(err)
59 }
60 if l := len(entries.Entries); l != 1 {
61 klog.Exitf("Unexpected number (%d) of entries received requesting index %d", l, idx)
62 }
63 logEntry, err := ct.RawLogEntryFromLeaf(idx, &entries.Entries[0])
64 if err != nil {
65 klog.Exitf("Failed to parse leaf %d: %v", idx, err)
66 }
67 return logEntry
68 }
69
70
71 idx := sort.Search(int(sth.TreeSize), func(idx int) bool {
72 klog.V(1).Infof("check timestamp at index %d", idx)
73 entry := getEntry(int64(idx))
74 return entry.Leaf.TimestampedEntry.Timestamp >= uint64(target)
75 })
76 when := ct.TimestampToTime(uint64(target))
77 if idx >= int(sth.TreeSize) {
78 fmt.Printf("No entry with timestamp>=%d (%v) found up to tree size %d\n", target, when, sth.TreeSize)
79 return
80 }
81 fmt.Printf("First entry with timestamp>=%d (%v) found at index %d\n", target, when, idx)
82 showRawLogEntry(getEntry(int64(idx)))
83 }
84
View as plain text