@@ -33,7 +33,7 @@ import (
3333 "golang.org/x/crypto/cryptobyte"
3434)
3535
36- func createTestCertBytes (dnsNames []string ) ([]byte , error ) {
36+ func createTestCertBytes (dnsNames []string , isPrecert bool ) ([]byte , error ) {
3737 priv , err := rsa .GenerateKey (rand .Reader , 2048 )
3838 if err != nil {
3939 return nil , err
@@ -55,52 +55,126 @@ func createTestCertBytes(dnsNames []string) ([]byte, error) {
5555 return nil , err
5656 }
5757
58+ var tbsDER []byte
59+ if isPrecert {
60+ parsed , err := x509 .ParseCertificate (certDER )
61+ if err != nil {
62+ return nil , err
63+ }
64+ tbsDER = parsed .RawTBSCertificate
65+ }
66+
5867 // Now marshal using cryptobyte into the form expected by mapFn
59- // version = 0, leafType = 0, timestamp = 12345678, certType = 0 (x509)
68+ // version = 0, leafType = 0, timestamp = 12345678
6069 var b cryptobyte.Builder
6170 b .AddUint8 (0 ) // version
6271 b .AddUint8 (0 ) // leafType
6372 b .AddUint64 (12345678 ) // timestamp
64- b .AddUint16 (0 ) // certType (x509)
65- b .AddUint24LengthPrefixed (func (b * cryptobyte.Builder ) {
66- b .AddBytes (certDER )
67- })
73+ if isPrecert {
74+ b .AddUint16 (1 ) // certType (precert)
75+ dummyIKH := make ([]byte , 32 )
76+ b .AddBytes (dummyIKH )
77+ b .AddUint24LengthPrefixed (func (b * cryptobyte.Builder ) {
78+ b .AddBytes (tbsDER )
79+ })
80+ } else {
81+ b .AddUint16 (0 ) // certType (x509)
82+ b .AddUint24LengthPrefixed (func (b * cryptobyte.Builder ) {
83+ b .AddBytes (certDER )
84+ })
85+ }
6886 return b .Bytes ()
6987}
7088
7189func TestMapFn (t * testing.T ) {
7290 testCases := []struct {
73- desc string
74- dnsNames []string
75- wantKeys []string
91+ desc string
92+ dnsNames []string
93+ wantKeys []string
94+ isPrecert bool
95+ rawBytes []byte
7696 }{
7797 {
78- desc : "standard domains and wildcards" ,
79- dnsNames : []string {"*.google.com" , "google.com" , "maps.google.com" },
80- wantKeys : []string {"google.com" , "maps.google.com" },
98+ desc : "standard domains and wildcards" ,
99+ dnsNames : []string {"*.google.com" , "google.com" , "maps.google.com" },
100+ wantKeys : []string {"google.com" , "maps.google.com" },
101+ isPrecert : false ,
102+ },
103+ {
104+ desc : "deeper subdomain" ,
105+ dnsNames : []string {"deep.maps.google.co.uk" },
106+ wantKeys : []string {"deep.maps.google.co.uk" , "maps.google.co.uk" , "google.co.uk" },
107+ isPrecert : false ,
108+ },
109+ {
110+ desc : "mixed case" ,
111+ dnsNames : []string {"MAPS.GOOGLE.COM" },
112+ wantKeys : []string {"maps.google.com" , "google.com" },
113+ isPrecert : false ,
114+ },
115+ {
116+ desc : "invalid or TLD" ,
117+ dnsNames : []string {"localhost" , "*.co.uk" },
118+ wantKeys : []string {"localhost" , "co.uk" },
119+ isPrecert : false ,
120+ },
121+ {
122+ desc : "precert: standard domains and wildcards" ,
123+ dnsNames : []string {"*.google.com" , "google.com" , "maps.google.com" },
124+ wantKeys : []string {"google.com" , "maps.google.com" },
125+ isPrecert : true ,
81126 },
82127 {
83- desc : "deeper subdomain" ,
84- dnsNames : []string {"deep.maps.google.co.uk" },
85- wantKeys : []string {"deep.maps.google.co.uk" , "maps.google.co.uk" , "google.co.uk" },
128+ desc : "precert: deeper subdomain" ,
129+ dnsNames : []string {"deep.maps.google.co.uk" },
130+ wantKeys : []string {"deep.maps.google.co.uk" , "maps.google.co.uk" , "google.co.uk" },
131+ isPrecert : true ,
86132 },
87133 {
88- desc : "mixed case " ,
89- dnsNames : []string { "MAPS.GOOGLE.COM" },
90- wantKeys : []string {"maps.google.com" , "google.com" },
134+ desc : "truncated header " ,
135+ rawBytes : []byte { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, // 11 bytes, header is 12 bytes
136+ wantKeys : []string {},
91137 },
92138 {
93- desc : "invalid or TLD" ,
94- dnsNames : []string {"localhost" , "*.co.uk" },
95- wantKeys : []string {"localhost" , "co.uk" },
139+ desc : "unknown cert type" ,
140+ rawBytes : []byte {
141+ 0 , // version
142+ 0 , // leafType
143+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // timestamp
144+ 0 , 99 , // certType = 99
145+ },
146+ wantKeys : []string {},
147+ },
148+ {
149+ desc : "precert truncated TBS" ,
150+ rawBytes : func () []byte {
151+ var b cryptobyte.Builder
152+ b .AddUint8 (0 ) // version
153+ b .AddUint8 (0 ) // leafType
154+ b .AddUint64 (12345678 ) // timestamp
155+ b .AddUint16 (1 ) // certType (precert)
156+ dummyIKH := make ([]byte , 32 )
157+ b .AddBytes (dummyIKH )
158+ b .AddUint24 (100 ) // length prefix 100
159+ b .AddBytes ([]byte {1 , 2 , 3 , 4 , 5 }) // only 5 bytes of data
160+ bytes , _ := b .Bytes ()
161+ return bytes
162+ }(),
163+ wantKeys : []string {},
96164 },
97165 }
98166
99167 for _ , tc := range testCases {
100168 t .Run (tc .desc , func (t * testing.T ) {
101- data , err := createTestCertBytes (tc .dnsNames )
102- if err != nil {
103- t .Fatalf ("failed to create test cert: %v" , err )
169+ var data []byte
170+ var err error
171+ if tc .rawBytes != nil {
172+ data = tc .rawBytes
173+ } else {
174+ data , err = createTestCertBytes (tc .dnsNames , tc .isPrecert )
175+ if err != nil {
176+ t .Fatalf ("failed to create test cert: %v" , err )
177+ }
104178 }
105179 hashes := mapFn (data )
106180
@@ -146,4 +220,3 @@ func TestMetricsEndpoint(t *testing.T) {
146220 t .Errorf ("GET /metrics: got status %d, want %d" , w .Code , http .StatusOK )
147221 }
148222}
149-
0 commit comments