1// Copyright 2019 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package tlog
6
7import (
8	"encoding/json"
9	"fmt"
10	"io/ioutil"
11	"net/http"
12	"net/url"
13	"os"
14	"testing"
15)
16
17func TestCertificateTransparency(t *testing.T) {
18	// Test that we can verify actual Certificate Transparency proofs.
19	// (The other tests check that we can verify our own proofs;
20	// this is a test that the two are compatible.)
21
22	if testing.Short() {
23		t.Skip("skipping in -short mode")
24	}
25
26	var root ctTree
27	httpGET(t, "http://ct.googleapis.com/logs/argon2020/ct/v1/get-sth", &root)
28
29	var leaf ctEntries
30	httpGET(t, "http://ct.googleapis.com/logs/argon2020/ct/v1/get-entries?start=10000&end=10000", &leaf)
31	hash := RecordHash(leaf.Entries[0].Data)
32
33	var rp ctRecordProof
34	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)
35
36	err := CheckRecord(rp.Proof, root.Size, root.Hash, 10000, hash)
37	if err != nil {
38		t.Fatal(err)
39	}
40
41	var tp ctTreeProof
42	httpGET(t, "http://ct.googleapis.com/logs/argon2020/ct/v1/get-sth-consistency?first=3654490&second="+fmt.Sprint(root.Size), &tp)
43
44	oh, _ := ParseHash("AuIZ5V6sDUj1vn3Y1K85oOaQ7y+FJJKtyRTl1edIKBQ=")
45	err = CheckTree(tp.Proof, root.Size, root.Hash, 3654490, oh)
46	if err != nil {
47		t.Fatal(err)
48	}
49}
50
51type ctTree struct {
52	Size int64 `json:"tree_size"`
53	Hash Hash  `json:"sha256_root_hash"`
54}
55
56type ctEntries struct {
57	Entries []*ctEntry
58}
59
60type ctEntry struct {
61	Data []byte `json:"leaf_input"`
62}
63
64type ctRecordProof struct {
65	Index int64       `json:"leaf_index"`
66	Proof RecordProof `json:"audit_path"`
67}
68
69type ctTreeProof struct {
70	Proof TreeProof `json:"consistency"`
71}
72
73func httpGET(t *testing.T, url string, targ interface{}) {
74	if testing.Verbose() {
75		println()
76		println(url)
77	}
78	resp, err := http.Get(url)
79	if err != nil {
80		t.Fatal(err)
81	}
82	defer resp.Body.Close()
83	data, err := ioutil.ReadAll(resp.Body)
84	if err != nil {
85		t.Fatal(err)
86	}
87	if testing.Verbose() {
88		os.Stdout.Write(data)
89	}
90	err = json.Unmarshal(data, targ)
91	if err != nil {
92		println(url)
93		os.Stdout.Write(data)
94		t.Fatal(err)
95	}
96}
97