| // Copyright 2019 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| package tlog | |
| import ( | |
| "encoding/json" | |
| "fmt" | |
| "io" | |
| "net/http" | |
| "net/url" | |
| "os" | |
| "testing" | |
| ) | |
| func TestCertificateTransparency(t *testing.T) { | |
| // Test that we can verify actual Certificate Transparency proofs. | |
| // (The other tests check that we can verify our own proofs; | |
| // this is a test that the two are compatible.) | |
| if testing.Short() { | |
| t.Skip("skipping in -short mode") | |
| } | |
| var root ctTree | |
| httpGET(t, "http://ct.googleapis.com/logs/argon2020/ct/v1/get-sth", &root) | |
| var leaf ctEntries | |
| httpGET(t, "http://ct.googleapis.com/logs/argon2020/ct/v1/get-entries?start=10000&end=10000", &leaf) | |
| hash := RecordHash(leaf.Entries[0].Data) | |
| var rp ctRecordProof | |
| httpGET(t, "http://ct.googleapis.com/logs/argon2020/ct/v1/get-proof-by-hash?tree_size="+fmt.Sprint(root.Size)+"&hash="+url.QueryEscape(hash.String()), &rp) | |
| err := CheckRecord(rp.Proof, root.Size, root.Hash, 10000, hash) | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| var tp ctTreeProof | |
| httpGET(t, "http://ct.googleapis.com/logs/argon2020/ct/v1/get-sth-consistency?first=3654490&second="+fmt.Sprint(root.Size), &tp) | |
| oh, _ := ParseHash("AuIZ5V6sDUj1vn3Y1K85oOaQ7y+FJJKtyRTl1edIKBQ=") | |
| err = CheckTree(tp.Proof, root.Size, root.Hash, 3654490, oh) | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| } | |
| type ctTree struct { | |
| Size int64 `json:"tree_size"` | |
| Hash Hash `json:"sha256_root_hash"` | |
| } | |
| type ctEntries struct { | |
| Entries []*ctEntry | |
| } | |
| type ctEntry struct { | |
| Data []byte `json:"leaf_input"` | |
| } | |
| type ctRecordProof struct { | |
| Index int64 `json:"leaf_index"` | |
| Proof RecordProof `json:"audit_path"` | |
| } | |
| type ctTreeProof struct { | |
| Proof TreeProof `json:"consistency"` | |
| } | |
| func httpGET(t *testing.T, url string, targ any) { | |
| if testing.Verbose() { | |
| println() | |
| println(url) | |
| } | |
| resp, err := http.Get(url) | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| defer resp.Body.Close() | |
| data, err := io.ReadAll(resp.Body) | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| if testing.Verbose() { | |
| os.Stdout.Write(data) | |
| } | |
| err = json.Unmarshal(data, targ) | |
| if err != nil { | |
| println(url) | |
| os.Stdout.Write(data) | |
| t.Fatal(err) | |
| } | |
| } |