1 |
747 |
jeremybenn |
// Copyright 2011 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 |
|
|
|
5 |
|
|
package x509
|
6 |
|
|
|
7 |
|
|
import (
|
8 |
|
|
"crypto/x509/pkix"
|
9 |
|
|
"encoding/pem"
|
10 |
|
|
"errors"
|
11 |
|
|
"strings"
|
12 |
|
|
"testing"
|
13 |
|
|
"time"
|
14 |
|
|
)
|
15 |
|
|
|
16 |
|
|
type verifyTest struct {
|
17 |
|
|
leaf string
|
18 |
|
|
intermediates []string
|
19 |
|
|
roots []string
|
20 |
|
|
currentTime int64
|
21 |
|
|
dnsName string
|
22 |
|
|
nilRoots bool
|
23 |
|
|
|
24 |
|
|
errorCallback func(*testing.T, int, error) bool
|
25 |
|
|
expectedChains [][]string
|
26 |
|
|
}
|
27 |
|
|
|
28 |
|
|
var verifyTests = []verifyTest{
|
29 |
|
|
{
|
30 |
|
|
leaf: googleLeaf,
|
31 |
|
|
intermediates: []string{thawteIntermediate},
|
32 |
|
|
roots: []string{verisignRoot},
|
33 |
|
|
currentTime: 1302726541,
|
34 |
|
|
dnsName: "www.google.com",
|
35 |
|
|
|
36 |
|
|
expectedChains: [][]string{
|
37 |
|
|
{"Google", "Thawte", "VeriSign"},
|
38 |
|
|
},
|
39 |
|
|
},
|
40 |
|
|
{
|
41 |
|
|
leaf: googleLeaf,
|
42 |
|
|
intermediates: []string{thawteIntermediate},
|
43 |
|
|
roots: []string{verisignRoot},
|
44 |
|
|
currentTime: 1302726541,
|
45 |
|
|
dnsName: "WwW.GooGLE.coM",
|
46 |
|
|
|
47 |
|
|
expectedChains: [][]string{
|
48 |
|
|
{"Google", "Thawte", "VeriSign"},
|
49 |
|
|
},
|
50 |
|
|
},
|
51 |
|
|
{
|
52 |
|
|
leaf: googleLeaf,
|
53 |
|
|
intermediates: []string{thawteIntermediate},
|
54 |
|
|
roots: []string{verisignRoot},
|
55 |
|
|
currentTime: 1302726541,
|
56 |
|
|
dnsName: "www.example.com",
|
57 |
|
|
|
58 |
|
|
errorCallback: expectHostnameError,
|
59 |
|
|
},
|
60 |
|
|
{
|
61 |
|
|
leaf: googleLeaf,
|
62 |
|
|
intermediates: []string{thawteIntermediate},
|
63 |
|
|
nilRoots: true, // verifies that we don't crash
|
64 |
|
|
currentTime: 1302726541,
|
65 |
|
|
dnsName: "www.google.com",
|
66 |
|
|
errorCallback: expectAuthorityUnknown,
|
67 |
|
|
},
|
68 |
|
|
{
|
69 |
|
|
leaf: googleLeaf,
|
70 |
|
|
intermediates: []string{thawteIntermediate},
|
71 |
|
|
roots: []string{verisignRoot},
|
72 |
|
|
currentTime: 1,
|
73 |
|
|
dnsName: "www.example.com",
|
74 |
|
|
|
75 |
|
|
errorCallback: expectExpired,
|
76 |
|
|
},
|
77 |
|
|
{
|
78 |
|
|
leaf: googleLeaf,
|
79 |
|
|
roots: []string{verisignRoot},
|
80 |
|
|
currentTime: 1302726541,
|
81 |
|
|
dnsName: "www.google.com",
|
82 |
|
|
|
83 |
|
|
errorCallback: expectAuthorityUnknown,
|
84 |
|
|
},
|
85 |
|
|
{
|
86 |
|
|
leaf: googleLeaf,
|
87 |
|
|
intermediates: []string{verisignRoot, thawteIntermediate},
|
88 |
|
|
roots: []string{verisignRoot},
|
89 |
|
|
currentTime: 1302726541,
|
90 |
|
|
dnsName: "www.google.com",
|
91 |
|
|
|
92 |
|
|
expectedChains: [][]string{
|
93 |
|
|
{"Google", "Thawte", "VeriSign"},
|
94 |
|
|
},
|
95 |
|
|
},
|
96 |
|
|
{
|
97 |
|
|
leaf: dnssecExpLeaf,
|
98 |
|
|
intermediates: []string{startComIntermediate},
|
99 |
|
|
roots: []string{startComRoot},
|
100 |
|
|
currentTime: 1302726541,
|
101 |
|
|
|
102 |
|
|
expectedChains: [][]string{
|
103 |
|
|
{"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority"},
|
104 |
|
|
},
|
105 |
|
|
},
|
106 |
|
|
{
|
107 |
|
|
leaf: dnssecExpLeaf,
|
108 |
|
|
intermediates: []string{startComIntermediate, startComRoot},
|
109 |
|
|
roots: []string{startComRoot},
|
110 |
|
|
currentTime: 1302726541,
|
111 |
|
|
|
112 |
|
|
expectedChains: [][]string{
|
113 |
|
|
{"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority"},
|
114 |
|
|
{"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority", "StartCom Certification Authority"},
|
115 |
|
|
},
|
116 |
|
|
},
|
117 |
|
|
}
|
118 |
|
|
|
119 |
|
|
func expectHostnameError(t *testing.T, i int, err error) (ok bool) {
|
120 |
|
|
if _, ok := err.(HostnameError); !ok {
|
121 |
|
|
t.Errorf("#%d: error was not a HostnameError: %s", i, err)
|
122 |
|
|
return false
|
123 |
|
|
}
|
124 |
|
|
return true
|
125 |
|
|
}
|
126 |
|
|
|
127 |
|
|
func expectExpired(t *testing.T, i int, err error) (ok bool) {
|
128 |
|
|
if inval, ok := err.(CertificateInvalidError); !ok || inval.Reason != Expired {
|
129 |
|
|
t.Errorf("#%d: error was not Expired: %s", i, err)
|
130 |
|
|
return false
|
131 |
|
|
}
|
132 |
|
|
return true
|
133 |
|
|
}
|
134 |
|
|
|
135 |
|
|
func expectAuthorityUnknown(t *testing.T, i int, err error) (ok bool) {
|
136 |
|
|
if _, ok := err.(UnknownAuthorityError); !ok {
|
137 |
|
|
t.Errorf("#%d: error was not UnknownAuthorityError: %s", i, err)
|
138 |
|
|
return false
|
139 |
|
|
}
|
140 |
|
|
return true
|
141 |
|
|
}
|
142 |
|
|
|
143 |
|
|
func certificateFromPEM(pemBytes string) (*Certificate, error) {
|
144 |
|
|
block, _ := pem.Decode([]byte(pemBytes))
|
145 |
|
|
if block == nil {
|
146 |
|
|
return nil, errors.New("failed to decode PEM")
|
147 |
|
|
}
|
148 |
|
|
return ParseCertificate(block.Bytes)
|
149 |
|
|
}
|
150 |
|
|
|
151 |
|
|
func TestVerify(t *testing.T) {
|
152 |
|
|
for i, test := range verifyTests {
|
153 |
|
|
opts := VerifyOptions{
|
154 |
|
|
Roots: NewCertPool(),
|
155 |
|
|
Intermediates: NewCertPool(),
|
156 |
|
|
DNSName: test.dnsName,
|
157 |
|
|
CurrentTime: time.Unix(test.currentTime, 0),
|
158 |
|
|
}
|
159 |
|
|
if test.nilRoots {
|
160 |
|
|
opts.Roots = nil
|
161 |
|
|
}
|
162 |
|
|
|
163 |
|
|
for j, root := range test.roots {
|
164 |
|
|
ok := opts.Roots.AppendCertsFromPEM([]byte(root))
|
165 |
|
|
if !ok {
|
166 |
|
|
t.Errorf("#%d: failed to parse root #%d", i, j)
|
167 |
|
|
return
|
168 |
|
|
}
|
169 |
|
|
}
|
170 |
|
|
|
171 |
|
|
for j, intermediate := range test.intermediates {
|
172 |
|
|
ok := opts.Intermediates.AppendCertsFromPEM([]byte(intermediate))
|
173 |
|
|
if !ok {
|
174 |
|
|
t.Errorf("#%d: failed to parse intermediate #%d", i, j)
|
175 |
|
|
return
|
176 |
|
|
}
|
177 |
|
|
}
|
178 |
|
|
|
179 |
|
|
leaf, err := certificateFromPEM(test.leaf)
|
180 |
|
|
if err != nil {
|
181 |
|
|
t.Errorf("#%d: failed to parse leaf: %s", i, err)
|
182 |
|
|
return
|
183 |
|
|
}
|
184 |
|
|
|
185 |
|
|
chains, err := leaf.Verify(opts)
|
186 |
|
|
|
187 |
|
|
if test.errorCallback == nil && err != nil {
|
188 |
|
|
t.Errorf("#%d: unexpected error: %s", i, err)
|
189 |
|
|
}
|
190 |
|
|
if test.errorCallback != nil {
|
191 |
|
|
if !test.errorCallback(t, i, err) {
|
192 |
|
|
return
|
193 |
|
|
}
|
194 |
|
|
}
|
195 |
|
|
|
196 |
|
|
if len(chains) != len(test.expectedChains) {
|
197 |
|
|
t.Errorf("#%d: wanted %d chains, got %d", i, len(test.expectedChains), len(chains))
|
198 |
|
|
}
|
199 |
|
|
|
200 |
|
|
// We check that each returned chain matches a chain from
|
201 |
|
|
// expectedChains but an entry in expectedChains can't match
|
202 |
|
|
// two chains.
|
203 |
|
|
seenChains := make([]bool, len(chains))
|
204 |
|
|
NextOutputChain:
|
205 |
|
|
for _, chain := range chains {
|
206 |
|
|
TryNextExpected:
|
207 |
|
|
for j, expectedChain := range test.expectedChains {
|
208 |
|
|
if seenChains[j] {
|
209 |
|
|
continue
|
210 |
|
|
}
|
211 |
|
|
if len(chain) != len(expectedChain) {
|
212 |
|
|
continue
|
213 |
|
|
}
|
214 |
|
|
for k, cert := range chain {
|
215 |
|
|
if strings.Index(nameToKey(&cert.Subject), expectedChain[k]) == -1 {
|
216 |
|
|
continue TryNextExpected
|
217 |
|
|
}
|
218 |
|
|
}
|
219 |
|
|
// we matched
|
220 |
|
|
seenChains[j] = true
|
221 |
|
|
continue NextOutputChain
|
222 |
|
|
}
|
223 |
|
|
t.Errorf("#%d: No expected chain matched %s", i, chainToDebugString(chain))
|
224 |
|
|
}
|
225 |
|
|
}
|
226 |
|
|
}
|
227 |
|
|
|
228 |
|
|
func chainToDebugString(chain []*Certificate) string {
|
229 |
|
|
var chainStr string
|
230 |
|
|
for _, cert := range chain {
|
231 |
|
|
if len(chainStr) > 0 {
|
232 |
|
|
chainStr += " -> "
|
233 |
|
|
}
|
234 |
|
|
chainStr += nameToKey(&cert.Subject)
|
235 |
|
|
}
|
236 |
|
|
return chainStr
|
237 |
|
|
}
|
238 |
|
|
|
239 |
|
|
func nameToKey(name *pkix.Name) string {
|
240 |
|
|
return strings.Join(name.Country, ",") + "/" + strings.Join(name.Organization, ",") + "/" + strings.Join(name.OrganizationalUnit, ",") + "/" + name.CommonName
|
241 |
|
|
}
|
242 |
|
|
|
243 |
|
|
const verisignRoot = `-----BEGIN CERTIFICATE-----
|
244 |
|
|
MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG
|
245 |
|
|
A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
|
246 |
|
|
cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
|
247 |
|
|
MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
|
248 |
|
|
BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt
|
249 |
|
|
YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
|
250 |
|
|
ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE
|
251 |
|
|
BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is
|
252 |
|
|
I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G
|
253 |
|
|
CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do
|
254 |
|
|
lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc
|
255 |
|
|
AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k
|
256 |
|
|
-----END CERTIFICATE-----
|
257 |
|
|
`
|
258 |
|
|
|
259 |
|
|
const thawteIntermediate = `-----BEGIN CERTIFICATE-----
|
260 |
|
|
MIIDIzCCAoygAwIBAgIEMAAAAjANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJV
|
261 |
|
|
UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDMgUHVi
|
262 |
|
|
bGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNTEzMDAw
|
263 |
|
|
MDAwWhcNMTQwNTEyMjM1OTU5WjBMMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhh
|
264 |
|
|
d3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBD
|
265 |
|
|
QTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1NNn0I0Vf67NMf59HZGhPwtx
|
266 |
|
|
PKzMyGT7Y/wySweUvW+Aui/hBJPAM/wJMyPpC3QrccQDxtLN4i/1CWPN/0ilAL/g
|
267 |
|
|
5/OIty0y3pg25gqtAHvEZEo7hHUD8nCSfQ5i9SGraTaEMXWQ+L/HbIgbBpV8yeWo
|
268 |
|
|
3nWhLHpo39XKHIdYYBkCAwEAAaOB/jCB+zASBgNVHRMBAf8ECDAGAQH/AgEAMAsG
|
269 |
|
|
A1UdDwQEAwIBBjARBglghkgBhvhCAQEEBAMCAQYwKAYDVR0RBCEwH6QdMBsxGTAX
|
270 |
|
|
BgNVBAMTEFByaXZhdGVMYWJlbDMtMTUwMQYDVR0fBCowKDAmoCSgIoYgaHR0cDov
|
271 |
|
|
L2NybC52ZXJpc2lnbi5jb20vcGNhMy5jcmwwMgYIKwYBBQUHAQEEJjAkMCIGCCsG
|
272 |
|
|
AQUFBzABhhZodHRwOi8vb2NzcC50aGF3dGUuY29tMDQGA1UdJQQtMCsGCCsGAQUF
|
273 |
|
|
BwMBBggrBgEFBQcDAgYJYIZIAYb4QgQBBgpghkgBhvhFAQgBMA0GCSqGSIb3DQEB
|
274 |
|
|
BQUAA4GBAFWsY+reod3SkF+fC852vhNRj5PZBSvIG3dLrWlQoe7e3P3bB+noOZTc
|
275 |
|
|
q3J5Lwa/q4FwxKjt6lM07e8eU9kGx1Yr0Vz00YqOtCuxN5BICEIlxT6Ky3/rbwTR
|
276 |
|
|
bcV0oveifHtgPHfNDs5IAn8BL7abN+AqKjbc1YXWrOU/VG+WHgWv
|
277 |
|
|
-----END CERTIFICATE-----
|
278 |
|
|
`
|
279 |
|
|
|
280 |
|
|
const googleLeaf = `-----BEGIN CERTIFICATE-----
|
281 |
|
|
MIIDITCCAoqgAwIBAgIQL9+89q6RUm0PmqPfQDQ+mjANBgkqhkiG9w0BAQUFADBM
|
282 |
|
|
MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg
|
283 |
|
|
THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0wOTEyMTgwMDAwMDBaFw0x
|
284 |
|
|
MTEyMTgyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh
|
285 |
|
|
MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw
|
286 |
|
|
FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC
|
287 |
|
|
gYEA6PmGD5D6htffvXImttdEAoN4c9kCKO+IRTn7EOh8rqk41XXGOOsKFQebg+jN
|
288 |
|
|
gtXj9xVoRaELGYW84u+E593y17iYwqG7tcFR39SDAqc9BkJb4SLD3muFXxzW2k6L
|
289 |
|
|
05vuuWciKh0R73mkszeK9P4Y/bz5RiNQl/Os/CRGK1w7t0UCAwEAAaOB5zCB5DAM
|
290 |
|
|
BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl
|
291 |
|
|
LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF
|
292 |
|
|
BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw
|
293 |
|
|
Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0
|
294 |
|
|
ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF
|
295 |
|
|
AAOBgQCfQ89bxFApsb/isJr/aiEdLRLDLE5a+RLizrmCUi3nHX4adpaQedEkUjh5
|
296 |
|
|
u2ONgJd8IyAPkU0Wueru9G2Jysa9zCRo1kNbzipYvzwY4OA8Ys+WAi0oR1A04Se6
|
297 |
|
|
z5nRUP8pJcA2NhUzUnC+MY+f6H/nEQyNv4SgQhqAibAxWEEHXw==
|
298 |
|
|
-----END CERTIFICATE-----`
|
299 |
|
|
|
300 |
|
|
const dnssecExpLeaf = `-----BEGIN CERTIFICATE-----
|
301 |
|
|
MIIGzTCCBbWgAwIBAgIDAdD6MA0GCSqGSIb3DQEBBQUAMIGMMQswCQYDVQQGEwJJ
|
302 |
|
|
TDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0
|
303 |
|
|
YWwgQ2VydGlmaWNhdGUgU2lnbmluZzE4MDYGA1UEAxMvU3RhcnRDb20gQ2xhc3Mg
|
304 |
|
|
MSBQcmltYXJ5IEludGVybWVkaWF0ZSBTZXJ2ZXIgQ0EwHhcNMTAwNzA0MTQ1MjQ1
|
305 |
|
|
WhcNMTEwNzA1MTA1NzA0WjCBwTEgMB4GA1UEDRMXMjIxMTM3LWxpOWE5dHhJRzZM
|
306 |
|
|
NnNyVFMxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVQZXJzb25hIE5vdCBWYWxpZGF0
|
307 |
|
|
ZWQxKTAnBgNVBAsTIFN0YXJ0Q29tIEZyZWUgQ2VydGlmaWNhdGUgTWVtYmVyMRsw
|
308 |
|
|
GQYDVQQDExJ3d3cuZG5zc2VjLWV4cC5vcmcxKDAmBgkqhkiG9w0BCQEWGWhvc3Rt
|
309 |
|
|
YXN0ZXJAZG5zc2VjLWV4cC5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
|
310 |
|
|
AoIBAQDEdF/22vaxrPbqpgVYMWi+alfpzBctpbfLBdPGuqOazJdCT0NbWcK8/+B4
|
311 |
|
|
X6OlSOURNIlwLzhkmwVsWdVv6dVSaN7d4yI/fJkvgfDB9+au+iBJb6Pcz8ULBfe6
|
312 |
|
|
D8HVvqKdORp6INzHz71z0sghxrQ0EAEkoWAZLh+kcn2ZHdcmZaBNUfjmGbyU6PRt
|
313 |
|
|
RjdqoP+owIaC1aktBN7zl4uO7cRjlYFdusINrh2kPP02KAx2W84xjxX1uyj6oS6e
|
314 |
|
|
7eBfvcwe8czW/N1rbE0CoR7h9+HnIrjnVG9RhBiZEiw3mUmF++Up26+4KTdRKbu3
|
315 |
|
|
+BL4yMpfd66z0+zzqu+HkvyLpFn5AgMBAAGjggL/MIIC+zAJBgNVHRMEAjAAMAsG
|
316 |
|
|
A1UdDwQEAwIDqDATBgNVHSUEDDAKBggrBgEFBQcDATAdBgNVHQ4EFgQUy04I5guM
|
317 |
|
|
drzfh2JQaXhgV86+4jUwHwYDVR0jBBgwFoAU60I00Jiwq5/0G2sI98xkLu8OLEUw
|
318 |
|
|
LQYDVR0RBCYwJIISd3d3LmRuc3NlYy1leHAub3Jngg5kbnNzZWMtZXhwLm9yZzCC
|
319 |
|
|
AUIGA1UdIASCATkwggE1MIIBMQYLKwYBBAGBtTcBAgIwggEgMC4GCCsGAQUFBwIB
|
320 |
|
|
FiJodHRwOi8vd3d3LnN0YXJ0c3NsLmNvbS9wb2xpY3kucGRmMDQGCCsGAQUFBwIB
|
321 |
|
|
FihodHRwOi8vd3d3LnN0YXJ0c3NsLmNvbS9pbnRlcm1lZGlhdGUucGRmMIG3Bggr
|
322 |
|
|
BgEFBQcCAjCBqjAUFg1TdGFydENvbSBMdGQuMAMCAQEagZFMaW1pdGVkIExpYWJp
|
323 |
|
|
bGl0eSwgc2VlIHNlY3Rpb24gKkxlZ2FsIExpbWl0YXRpb25zKiBvZiB0aGUgU3Rh
|
324 |
|
|
cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUG9saWN5IGF2YWlsYWJsZSBh
|
325 |
|
|
dCBodHRwOi8vd3d3LnN0YXJ0c3NsLmNvbS9wb2xpY3kucGRmMGEGA1UdHwRaMFgw
|
326 |
|
|
KqAooCaGJGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL2NydDEtY3JsLmNybDAqoCig
|
327 |
|
|
JoYkaHR0cDovL2NybC5zdGFydHNzbC5jb20vY3J0MS1jcmwuY3JsMIGOBggrBgEF
|
328 |
|
|
BQcBAQSBgTB/MDkGCCsGAQUFBzABhi1odHRwOi8vb2NzcC5zdGFydHNzbC5jb20v
|
329 |
|
|
c3ViL2NsYXNzMS9zZXJ2ZXIvY2EwQgYIKwYBBQUHMAKGNmh0dHA6Ly93d3cuc3Rh
|
330 |
|
|
cnRzc2wuY29tL2NlcnRzL3N1Yi5jbGFzczEuc2VydmVyLmNhLmNydDAjBgNVHRIE
|
331 |
|
|
HDAahhhodHRwOi8vd3d3LnN0YXJ0c3NsLmNvbS8wDQYJKoZIhvcNAQEFBQADggEB
|
332 |
|
|
ACXj6SB59KRJPenn6gUdGEqcta97U769SATyiQ87i9er64qLwvIGLMa3o2Rcgl2Y
|
333 |
|
|
kghUeyLdN/EXyFBYA8L8uvZREPoc7EZukpT/ZDLXy9i2S0jkOxvF2fD/XLbcjGjM
|
334 |
|
|
iEYG1/6ASw0ri9C0k4oDDoJLCoeH9++yqF7SFCCMcDkJqiAGXNb4euDpa8vCCtEQ
|
335 |
|
|
CSS+ObZbfkreRt3cNCf5LfCXe9OsTnCfc8Cuq81c0oLaG+SmaLUQNBuToq8e9/Zm
|
336 |
|
|
+b+/a3RVjxmkV5OCcGVBxsXNDn54Q6wsdw0TBMcjwoEndzpLS7yWgFbbkq5ZiGpw
|
337 |
|
|
Qibb2+CfKuQ+WFV1GkVQmVA=
|
338 |
|
|
-----END CERTIFICATE-----`
|
339 |
|
|
|
340 |
|
|
const startComIntermediate = `-----BEGIN CERTIFICATE-----
|
341 |
|
|
MIIGNDCCBBygAwIBAgIBGDANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW
|
342 |
|
|
MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
|
343 |
|
|
Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
|
344 |
|
|
dGlvbiBBdXRob3JpdHkwHhcNMDcxMDI0MjA1NDE3WhcNMTcxMDI0MjA1NDE3WjCB
|
345 |
|
|
jDELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xKzApBgNVBAsT
|
346 |
|
|
IlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNpZ25pbmcxODA2BgNVBAMTL1N0
|
347 |
|
|
YXJ0Q29tIENsYXNzIDEgUHJpbWFyeSBJbnRlcm1lZGlhdGUgU2VydmVyIENBMIIB
|
348 |
|
|
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtonGrO8JUngHrJJj0PREGBiE
|
349 |
|
|
gFYfka7hh/oyULTTRwbw5gdfcA4Q9x3AzhA2NIVaD5Ksg8asWFI/ujjo/OenJOJA
|
350 |
|
|
pgh2wJJuniptTT9uYSAK21ne0n1jsz5G/vohURjXzTCm7QduO3CHtPn66+6CPAVv
|
351 |
|
|
kvek3AowHpNz/gfK11+AnSJYUq4G2ouHI2mw5CrY6oPSvfNx23BaKA+vWjhwRRI/
|
352 |
|
|
ME3NO68X5Q/LoKldSKqxYVDLNM08XMML6BDAjJvwAwNi/rJsPnIO7hxDKslIDlc5
|
353 |
|
|
xDEhyBDBLIf+VJVSH1I8MRKbf+fAoKVZ1eKPPvDVqOHXcDGpxLPPr21TLwb0pwID
|
354 |
|
|
AQABo4IBrTCCAakwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
|
355 |
|
|
VR0OBBYEFOtCNNCYsKuf9BtrCPfMZC7vDixFMB8GA1UdIwQYMBaAFE4L7xqkQFul
|
356 |
|
|
F2mHMMo0aEPQQa7yMGYGCCsGAQUFBwEBBFowWDAnBggrBgEFBQcwAYYbaHR0cDov
|
357 |
|
|
L29jc3Auc3RhcnRzc2wuY29tL2NhMC0GCCsGAQUFBzAChiFodHRwOi8vd3d3LnN0
|
358 |
|
|
YXJ0c3NsLmNvbS9zZnNjYS5jcnQwWwYDVR0fBFQwUjAnoCWgI4YhaHR0cDovL3d3
|
359 |
|
|
dy5zdGFydHNzbC5jb20vc2ZzY2EuY3JsMCegJaAjhiFodHRwOi8vY3JsLnN0YXJ0
|
360 |
|
|
c3NsLmNvbS9zZnNjYS5jcmwwgYAGA1UdIAR5MHcwdQYLKwYBBAGBtTcBAgEwZjAu
|
361 |
|
|
BggrBgEFBQcCARYiaHR0cDovL3d3dy5zdGFydHNzbC5jb20vcG9saWN5LnBkZjA0
|
362 |
|
|
BggrBgEFBQcCARYoaHR0cDovL3d3dy5zdGFydHNzbC5jb20vaW50ZXJtZWRpYXRl
|
363 |
|
|
LnBkZjANBgkqhkiG9w0BAQUFAAOCAgEAIQlJPqWIbuALi0jaMU2P91ZXouHTYlfp
|
364 |
|
|
tVbzhUV1O+VQHwSL5qBaPucAroXQ+/8gA2TLrQLhxpFy+KNN1t7ozD+hiqLjfDen
|
365 |
|
|
xk+PNdb01m4Ge90h2c9W/8swIkn+iQTzheWq8ecf6HWQTd35RvdCNPdFWAwRDYSw
|
366 |
|
|
xtpdPvkBnufh2lWVvnQce/xNFE+sflVHfXv0pQ1JHpXo9xLBzP92piVH0PN1Nb6X
|
367 |
|
|
t1gW66pceG/sUzCv6gRNzKkC4/C2BBL2MLERPZBOVmTX3DxDX3M570uvh+v2/miI
|
368 |
|
|
RHLq0gfGabDBoYvvF0nXYbFFSF87ICHpW7LM9NfpMfULFWE7epTj69m8f5SuauNi
|
369 |
|
|
YpaoZHy4h/OZMn6SolK+u/hlz8nyMPyLwcKmltdfieFcNID1j0cHL7SRv7Gifl9L
|
370 |
|
|
WtBbnySGBVFaaQNlQ0lxxeBvlDRr9hvYqbBMflPrj0jfyjO1SPo2ShpTpjMM0InN
|
371 |
|
|
SRXNiTE8kMBy12VLUjWKRhFEuT2OKGWmPnmeXAhEKa2wNREuIU640ucQPl2Eg7PD
|
372 |
|
|
wuTSxv0JS3QJ3fGz0xk+gA2iCxnwOOfFwq/iI9th4p1cbiCJSS4jarJiwUW0n6+L
|
373 |
|
|
p/EiO/h94pDQehn7Skzj0n1fSoMD7SfWI55rjbRZotnvbIIp3XUZPD9MEI3vu3Un
|
374 |
|
|
0q6Dp6jOW6c=
|
375 |
|
|
-----END CERTIFICATE-----`
|
376 |
|
|
|
377 |
|
|
const startComRoot = `-----BEGIN CERTIFICATE-----
|
378 |
|
|
MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW
|
379 |
|
|
MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
|
380 |
|
|
Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
|
381 |
|
|
dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM2WhcNMzYwOTE3MTk0NjM2WjB9
|
382 |
|
|
MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi
|
383 |
|
|
U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh
|
384 |
|
|
cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA
|
385 |
|
|
A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk
|
386 |
|
|
pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf
|
387 |
|
|
OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C
|
388 |
|
|
Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT
|
389 |
|
|
Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi
|
390 |
|
|
HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM
|
391 |
|
|
Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w
|
392 |
|
|
+2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+
|
393 |
|
|
Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3
|
394 |
|
|
Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B
|
395 |
|
|
26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID
|
396 |
|
|
AQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE
|
397 |
|
|
FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9j
|
398 |
|
|
ZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3Js
|
399 |
|
|
LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFM
|
400 |
|
|
BgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUHAgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0
|
401 |
|
|
Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRwOi8vY2VydC5zdGFy
|
402 |
|
|
dGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYgU3Rh
|
403 |
|
|
cnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlh
|
404 |
|
|
YmlsaXR5LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2Yg
|
405 |
|
|
dGhlIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFp
|
406 |
|
|
bGFibGUgYXQgaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwEQYJ
|
407 |
|
|
YIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNT
|
408 |
|
|
TCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOCAgEAFmyZ
|
409 |
|
|
9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8
|
410 |
|
|
jhvh3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUW
|
411 |
|
|
FjgKXlf2Ysd6AgXmvB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJz
|
412 |
|
|
ewT4F+irsfMuXGRuczE6Eri8sxHkfY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1
|
413 |
|
|
ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3fsNrarnDy0RLrHiQi+fHLB5L
|
414 |
|
|
EUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZEoalHmdkrQYu
|
415 |
|
|
L6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq
|
416 |
|
|
yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuC
|
417 |
|
|
O3NJo2pXh5Tl1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6V
|
418 |
|
|
um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh
|
419 |
|
|
NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14=
|
420 |
|
|
-----END CERTIFICATE-----`
|