1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package x509ext_test
16
17 import (
18 "encoding/hex"
19 "encoding/pem"
20 "fmt"
21 "strings"
22 "testing"
23 "time"
24
25 "github.com/google/certificate-transparency-go/gossip/minimal/x509ext"
26 "github.com/google/certificate-transparency-go/tls"
27 "github.com/google/certificate-transparency-go/x509"
28 "github.com/google/certificate-transparency-go/x509/pkix"
29
30 ct "github.com/google/certificate-transparency-go"
31 )
32
33 var (
34
35 pilotPubKeyPEM = []byte(`-----BEGIN PUBLIC KEY-----
36 MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfahLEimAoz2t01p3uMziiLOl/fHT
37 DM0YDOhBRuiBARsV4UvxG2LdNgoIGLrtCzWE0J5APC2em4JlvR8EEEFMoA==
38 -----END PUBLIC KEY-----`)
39 )
40
41 func TestSTHFromCert(t *testing.T) {
42 rawPubKey, _ := pem.Decode(pilotPubKeyPEM)
43 pubKey, _, _, err := ct.PublicKeyFromPEM(pilotPubKeyPEM)
44 if err != nil {
45 t.Fatalf("failed to decode test pubkey data: %v", err)
46 }
47 validSTH := x509ext.LogSTHInfo{
48 LogURL: []byte("http://ct.example.com/log"),
49 Version: 0,
50 TreeSize: 7834120,
51 Timestamp: 1519395540364,
52 SHA256RootHash: [...]byte{
53 0xfe, 0xc0, 0xed, 0xe1, 0xbe, 0xf1, 0xa2, 0x25, 0xc3, 0x72, 0xa6, 0x44, 0x1b, 0xa2, 0xd5, 0xdd, 0x3b, 0xbb, 0x9b, 0x7b, 0xa9, 0x79, 0xd1, 0xa7, 0x03, 0xe7, 0xfe, 0x81, 0x49, 0x75, 0x85, 0xfb,
54 },
55 TreeHeadSignature: ct.DigitallySigned{
56 Algorithm: tls.SignatureAndHashAlgorithm{Hash: tls.SHA256, Signature: tls.ECDSA},
57 Signature: dehex("220164e031604aa2a0b68887ba668cefb3e0046e455d6323c3df38b8d50108895d70220146199ee1d759a029d8b37ce8701d2ca47a387bad8ac8ef1cb84b77bc0820ed"),
58 },
59 }
60 sthData, err := tls.Marshal(validSTH)
61 if err != nil {
62 t.Fatalf("failed to marshal STH: %v", err)
63 }
64
65 var tests = []struct {
66 name string
67 cert x509.Certificate
68 wantErr string
69 }{
70 {
71 name: "ValidSTH",
72 cert: x509.Certificate{
73 NotBefore: time.Now(),
74 NotAfter: time.Now().Add(24 * time.Hour),
75 PublicKey: pubKey,
76 RawSubjectPublicKeyInfo: rawPubKey.Bytes,
77 Subject: pkix.Name{
78 CommonName: "Test STH holder",
79 },
80 Extensions: []pkix.Extension{
81 {Id: x509ext.OIDExtensionCTSTH, Critical: false, Value: sthData},
82 },
83 },
84 },
85 {
86 name: "MissingSTH",
87 cert: x509.Certificate{
88 NotBefore: time.Now(),
89 NotAfter: time.Now().Add(24 * time.Hour),
90 Subject: pkix.Name{
91 CommonName: "Test STH holder",
92 },
93 },
94 wantErr: "no STH extension found",
95 },
96 {
97 name: "TrailingData",
98 cert: x509.Certificate{
99 NotBefore: time.Now(),
100 NotAfter: time.Now().Add(24 * time.Hour),
101 Subject: pkix.Name{
102 CommonName: "Test STH holder",
103 },
104 Extensions: []pkix.Extension{
105 {Id: x509ext.OIDExtensionCTSTH, Critical: false, Value: append(sthData, 0xff)},
106 },
107 },
108 wantErr: "trailing data",
109 },
110 {
111 name: "InvalidSTH",
112 cert: x509.Certificate{
113 NotBefore: time.Now(),
114 NotAfter: time.Now().Add(24 * time.Hour),
115 Subject: pkix.Name{
116 CommonName: "Test STH holder",
117 },
118 Extensions: []pkix.Extension{
119 {Id: x509ext.OIDExtensionCTSTH, Critical: false, Value: []byte{0xff}},
120 },
121 },
122 wantErr: "failed to unmarshal",
123 },
124 }
125
126 for _, test := range tests {
127 t.Run(test.name, func(t *testing.T) {
128 got, err := x509ext.STHFromCert(&test.cert)
129 if err != nil {
130 if test.wantErr == "" {
131 t.Errorf("STHFromCert(%+v)=nil,%v; want _,nil", test.cert, err)
132 } else if !strings.Contains(err.Error(), test.wantErr) {
133 t.Errorf("STHFromCert(%+v)=nil,%v; want nil,err containing %q", test.cert, err, test.wantErr)
134 }
135 return
136 }
137 if test.wantErr != "" {
138 t.Errorf("STHFromCert(%+v)=_,nil; want nil,err containing %q", test.cert, test.wantErr)
139 }
140 t.Logf("retrieved STH %+v", got)
141 })
142 }
143 }
144
145 func dehex(h string) []byte {
146 d, err := hex.DecodeString(h)
147 if err != nil {
148 panic(fmt.Sprintf("hard-coded data %q failed to decode! %v", h, err))
149 }
150 return d
151 }
152
View as plain text