aboutsummaryrefslogtreecommitdiff
path: root/own.go
blob: ae3e457c4b367664a444831fcd8f33325665d5ec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package main

// func audit(d *db) error {
// 	log.Printf("starting audit of %s...", d.host)
// 	size, hash, err := d.getLatest()
// 	if err != nil {
// 		return err
// 	}
// 	log.Printf("db size %d", size)
// 	log.Printf("db hash %s", hash)
// 	return nil
// }

// type db struct {
// 	host         string
// 	key          string
// 	pollInterval time.Duration
// }

// // httpGet makes a GET request to the specified path of the database and
// // returns a byte slice of the response body.
// func (d *db) httpGet(path string) ([]byte, error) {
// 	client := &http.Client{}
// 	resp, err := client.Get("https://" + d.host + path)
// 	if err != nil {
// 		return nil, err
// 	}
// 	defer resp.Body.Close()
// 	var body bytes.Buffer
// 	if _, err := io.Copy(&body, resp.Body); err != nil {
// 		return nil, fmt.Errorf("could not read response body: %w", err)
// 	}
// 	return body.Bytes(), nil
// }

// // verifyNote takes a signed byte slice, verifies the signature against the
// // db's public key. If successful, the note content is returned, otherwise, an
// // error.
// func (d *db) verifyNote(b []byte) (string, error) {
// 	verifier, err := note.NewVerifier(d.key)
// 	if err != nil {
// 		return "", err
// 	}
// 	verifiers := note.VerifierList(verifier)
// 	msg, err := note.Open(b, verifiers)
// 	if err != nil {
// 		return "", err
// 	}
// 	return msg.Text, nil
// }

// // bootstrapMonitor fetches and verifies the current tree starting from the
// // first log entry, and returns the current verified size and hash.
// func (d *db) bootstrapMonitor() (int, string, error) {
// 	log.Printf("bootstrapping monitor")
// 	log.Printf("TODO: implement fully")
// 	log.Printf("verified until size 163038")
// 	return 163038, "S1dhskM/kuUJUOCz3InBRhl0vFiHxr0INft+24ClisI=", nil

// 	// TODO: implement

// 	// 1. Fetch the current STH (section 4.3)
// 	// 2. Verify the STH signature
// 	// size, hash, err := d.getLatest()
// 	// if err != nil {
// 	// 	return err
// 	// }

// 	// 3. Fetch all entries in the tree corresponding to the STH (section 4.6)

// 	// 4. Confirm that the tree made from the fetched entries produces the same
// 	// hash as that in the STH.
// }

// // monitor monitors the db to ensure it behaves correctly, using the algorithm
// // for CT logs specified in RFC 6952 section 3.5.
// func (d *db) monitor() error {
// 	log.Printf("starting monitor")
// 	size, hash, err := d.bootstrapMonitor()
// 	if err != nil {
// 		return err
// 	}
// 	log.Printf("successfully verified merkle tree proof until size %d and hash %s", size, hash)

// 	// 5. Fetch the current STH (section 4.3). Repeat until the STH changes.
// 	// 6. Verify the STH signature.
// 	log.Printf("waiting for a tree size greater than %d", size)
// 	newSize, newHash, err := d.awaitNewSTH(size)
// 	if err != nil {
// 		return err
// 	}
// 	log.Printf("got new STH with size %d and hash %s", newSize, newHash)

// 	// 7. Fetch all the new entries in the tree corresponding to the STH (section
// 	// 4.6). If they remain unavailable for an extended period, then this should
// 	// be viewed as misbehavior on the part of the log.

// 	// 8. Fetch a consistency proof for the new STH with the previous STH
// 	// (section 4.4).

// 	// 9. Verify the consistency proof.

// 	// 10. Verify that the new entries generate the corresponding elements in the
// 	// consistency proof.

// 	// 11. Go to step 5.

// 	return nil
// }

// // awaitNewSTH periodically checks and verifies the current STH. If the latest
// // tree size differs from the previous size, the new verified size and hash are
// // returned.
// func (d *db) awaitNewSTH(prevSize int) (int, string, error) {
// 	for {
// 		log.Printf("sleeping...")
// 		time.Sleep(d.pollInterval)
// 		log.Printf("checking latest tree size")
// 		size, hash, err := d.getLatest()
// 		if err != nil {
// 			return 0, "", err
// 		}
// 		if size < prevSize {
// 			return 0, "", fmt.Errorf("misbehaving log: latest log contains %d entries but previously reported %d", size, prevSize)
// 		}
// 		if size != prevSize {
// 			log.Printf("found a new STH (size=%d)", size)
// 			return size, hash, nil
// 		}
// 		log.Printf("tree sizes match")
// 	}
// }

// // getLatest fetches and verifies the latest signed tree head hash and database
// // size.
// func (d *db) getLatest() (int, string, error) {
// 	body, err := d.httpGet("/latest")
// 	if err != nil {
// 		return 0, "", fmt.Errorf("could not fetch latest: %w", err)
// 	}
// 	msg, err := d.verifyNote(body)
// 	if err != nil {
// 		return 0, "", fmt.Errorf("could not verify note: %w", err)
// 	}
// 	parts := strings.Split(msg, "\n")
// 	if len(parts) != 4 {
// 		return 0, "", fmt.Errorf("could not parse latest: expected %d lines but got %d", 4, len(parts))
// 	}
// 	size, err := strconv.Atoi(parts[1])
// 	if err != nil {
// 		return 0, "", fmt.Errorf("could not parse tree size: %w", err)
// 	}
// 	hash := parts[2]
// 	return size, hash, nil
// }