1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339
|
package bundler
// This test file contains tests on checking the correctness of BundleFromPEM
import (
"testing"
)
// A helper structure that defines a BundleFromPEM test case.
type pemTest struct {
// PEM cert to be bundled
cert []byte
// PEM private key to be bundled
key []byte
// PEM intermediate certificates to be considered when bundling
inters []byte
// Bundler creation function
bundlerConstructor func(*testing.T) (b *Bundler)
// Error checking function
errorCallback func(*testing.T, error)
// Bundle checking function
bundleChecking func(*testing.T, *Bundle)
}
// BundleFromPEM test cases.
var pemTests = []pemTest{
{
cert: GoDaddyIntermediateCert,
bundlerConstructor: newBundler,
errorCallback: nil,
bundleChecking: ExpectBundleLength(1),
},
{
cert: []byte(""),
bundlerConstructor: newBundler,
errorCallback: ExpectErrorMessage("\"code\":1002"),
},
{
cert: corruptCert,
bundlerConstructor: newBundler,
errorCallback: ExpectErrorMessage("\"code\":1002"),
},
{
cert: garbageCert,
bundlerConstructor: newBundler,
errorCallback: ExpectErrorMessage("\"code\":1003"),
},
{
cert: selfSignedCert,
bundlerConstructor: newBundler,
errorCallback: ExpectErrorMessage("\"code\":1100"),
},
// 121X errors are X509.CertificateInvalidError. This test
// covers the code path leads to all 121X errors.
{
cert: expiredCert,
bundlerConstructor: newBundler,
errorCallback: ExpectErrorMessage("\"code\":1211"),
},
// With a empty root cert pool, the valid root cert
// is seen as issued by an unknown authority.
{
cert: GoDaddyIntermediateCert,
bundlerConstructor: newBundlerWithoutRoots,
errorCallback: ExpectErrorMessage("\"code\":1220"),
},
}
// TestBundleFromPEM goes through the test cases defined in pemTests and run them through. See below for test case definitions.
func TestBundleFromPEM(t *testing.T) {
for i, test := range pemTests {
b := test.bundlerConstructor(t)
bundle, err := b.BundleFromPEMorDER(test.cert, test.key, Optimal, "")
if test.errorCallback != nil {
test.errorCallback(t, err)
} else {
if err != nil {
t.Errorf("expected no error. but an error occurred at %d-th test: %s", i, err.Error())
}
if test.bundleChecking != nil {
test.bundleChecking(t, bundle)
}
}
}
}
// GoDaddy intermediate cert valid until year 2034
var GoDaddyRootCert = []byte(`-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
ReYNnyicsbkqWletNw+vHX/bvZ8=
-----END CERTIFICATE-----`)
// GoDaddy intermediate cert valid until year 2026
var GoDaddyIntermediateCert = []byte(`-----BEGIN CERTIFICATE-----
MIIE3jCCA8agAwIBAgICAwEwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCVVMx
ITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g
RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMTYw
MTU0MzdaFw0yNjExMTYwMTU0MzdaMIHKMQswCQYDVQQGEwJVUzEQMA4GA1UECBMH
QXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEaMBgGA1UEChMRR29EYWRkeS5j
b20sIEluYy4xMzAxBgNVBAsTKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5j
b20vcmVwb3NpdG9yeTEwMC4GA1UEAxMnR28gRGFkZHkgU2VjdXJlIENlcnRpZmlj
YXRpb24gQXV0aG9yaXR5MREwDwYDVQQFEwgwNzk2OTI4NzCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAMQt1RWMnCZM7DI161+4WQFapmGBWTtwY6vj3D3H
KrjJM9N55DrtPDAjhI6zMBS2sofDPZVUBJ7fmd0LJR4h3mUpfjWoqVTr9vcyOdQm
VZWt7/v+WIbXnvQAjYwqDL1CBM6nPwT27oDyqu9SoWlm2r4arV3aLGbqGmu75RpR
SgAvSMeYddi5Kcju+GZtCpyz8/x4fKL4o/K1w/O5epHBp+YlLpyo7RJlbmr2EkRT
cDCVw5wrWCs9CHRK8r5RsL+H0EwnWGu1NcWdrxcx+AuP7q2BNgWJCJjPOq8lh8BJ
6qf9Z/dFjpfMFDniNoW1fho3/Rb2cRGadDAW/hOUoz+EDU8CAwEAAaOCATIwggEu
MB0GA1UdDgQWBBT9rGEyk2xF1uLuhV+auud2mWjM5zAfBgNVHSMEGDAWgBTSxLDS
kdRMEXGzYcs9of7dqGrU4zASBgNVHRMBAf8ECDAGAQH/AgEAMDMGCCsGAQUFBwEB
BCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZ29kYWRkeS5jb20wRgYDVR0f
BD8wPTA7oDmgN4Y1aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBv
c2l0b3J5L2dkcm9vdC5jcmwwSwYDVR0gBEQwQjBABgRVHSAAMDgwNgYIKwYBBQUH
AgEWKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeTAO
BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBANKGwOy9+aG2Z+5mC6IG
OgRQjhVyrEp0lVPLN8tESe8HkGsz2ZbwlFalEzAFPIUyIXvJxwqoJKSQ3kbTJSMU
A2fCENZvD117esyfxVgqwcSeIaha86ykRvOe5GPLL5CkKSkB2XIsKd83ASe8T+5o
0yGPwLPk9Qnt0hCqU7S+8MxZC9Y7lhyVJEnfzuz9p0iRFEUOOjZv2kWzRaJBydTX
RE4+uXR21aITVSzGh6O1mawGhId/dQb8vxRMDsxuxN89txJx9OjxUUAiKEngHUuH
qDTMBqLdElrRhjZkAzVvb3du6/KFUJheqwNTrZEjYx8WnM25sgVjOuH0aBsXBTWV
U+4=
-----END CERTIFICATE-----`)
// This is the same GoDaddy cert above except the last line is corrupted.
var corruptCert = []byte(`-----BEGIN CERTIFICATE-----
MIIE3jCCA8agAwIBAgICAwEwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCVVMx
ITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g
RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMTYw
MTU0MzdaFw0yNjExMTYwMTU0MzdaMIHKMQswCQYDVQQGEwJVUzEQMA4GA1UECBMH
QXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEaMBgGA1UEChMRR29EYWRkeS5j
b20sIEluYy4xMzAxBgNVBAsTKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5j
b20vcmVwb3NpdG9yeTEwMC4GA1UEAxMnR28gRGFkZHkgU2VjdXJlIENlcnRpZmlj
YXRpb24gQXV0aG9yaXR5MREwDwYDVQQFEwgwNzk2OTI4NzCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAMQt1RWMnCZM7DI161+4WQFapmGBWTtwY6vj3D3H
KrjJM9N55DrtPDAjhI6zMBS2sofDPZVUBJ7fmd0LJR4h3mUpfjWoqVTr9vcyOdQm
VZWt7/v+WIbXnvQAjYwqDL1CBM6nPwT27oDyqu9SoWlm2r4arV3aLGbqGmu75RpR
SgAvSMeYddi5Kcju+GZtCpyz8/x4fKL4o/K1w/O5epHBp+YlLpyo7RJlbmr2EkRT
cDCVw5wrWCs9CHRK8r5RsL+H0EwnWGu1NcWdrxcx+AuP7q2BNgWJCJjPOq8lh8BJ
6qf9Z/dFjpfMFDniNoW1fho3/Rb2cRGadDAW/hOUoz+EDU8CAwEAAaOCATIwggEu
MB0GA1UdDgQWBBT9rGEyk2xF1uLuhV+auud2mWjM5zAfBgNVHSMEGDAWgBTSxLDS
kdRMEXGzYcs9of7dqGrU4zASBgNVHRMBAf8ECDAGAQH/AgEAMDMGCCsGAQUFBwEB
BCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZ29kYWRkeS5jb20wRgYDVR0f
BD8wPTA7oDmgN4Y1aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBv
c2l0b3J5L2dkcm9vdC5jcmwwSwYDVR0gBEQwQjBABgRVHSAAMDgwNgYIKwYBBQUH
AgEWKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeTAO
BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBANKGwOy9+aG2Z+5mC6IG
OgRQjhVyrEp0lVPLN8tESe8HkGsz2ZbwlFalEzAFPIUyIXvJxwqoJKSQ3kbTJSMU
A2fCENZvD117esyfxVgqwcSeIaha86ykRvOe5GPLL5CkKSkB2XIsKd83ASe8T+5o
0yGPwLPk9Qnt0hCqU7S+8MxZC9Y7lhyVJEnfzuz9p0iRFEUOOjZv2kWzRaJBydTX
RE4+uXR21aITVSzGh6O1mawGhId/dQb8vxRMDsxuxN89txJx9OjxUUAiKEngHUuH
qDTMBqLdElrRhjZkAzVvb3du6/KFUJheqwNTrZEjYx8WnM25sgVjOuH0aBsXBTWV
CORRUPTED
-----END CERTIFICATE-----`)
// A garbage cert, which can be decoded into ill-formed cert
var garbageCert = []byte(`-----BEGIN CERTIFICATE-----
MIICATCCAWoCCQDidF+uNJR6czANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJB
cyBQdHkgTHRkMB4XDTEyMDUwMTIyNTUxN1oXDTEzMDUwMTIyNTUxN1owRTELMAkG
A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0
nodhz31kLEJoeLSkRmrv8l7exkGtO0REtIbirj9BBy64ZXVBE7khKGO2cnM8U7yj
w7Ntfh+IvCjZVA3d2XqHS3Pjrt4HmU/cGCONE8+NEXoqdzLUDPOix1qDDRBvXs81
IFdpZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtpjl
KAV2qh6CYHZbdqixhDerjvJcD4Nsd7kExEZfHuECAwEAATANBgkqhkiG9w0BAQUF
AAOBgQCyOqs7+qpMrYCgL6OamDeCVojLoEp036PsnaYWf2NPmsVXdpYW40Foyyjp
VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
iv5otkxO5rxtGPv7o2J1eMBpCuSkydvoz3Ey/QwGqbBwEXQ4xYCgra336gqW2KQt
+LnDCkE8f5oBhCIisExc2i8PDvsRsY70g/2gs983ImJjVR8sDw==
-----END CERTIFICATE-----`)
// A expired cert
var expiredCert = []byte(`-----BEGIN CERTIFICATE-----
MIIHlTCCBn2gAwIBAgIQCgFBPgAAATyS0MsAAAAAAjANBgkqhkiG9w0BAQUFADBY
MQswCQYDVQQGEwJVUzEXMBUGA1UECgwOSWRlblRydXN0IExMQy4xFzAVBgNVBAsM
DlRydXN0SUQgU2VydmVyMRcwFQYDVQQDDA5UcnVzdElEIENBIEE1MTAeFw0xMzAx
MzEyMjUzNDJaFw0xMzAyMDEyMjUzNDJaMIGIMSEwHwYDVQQDDBhleHBpcmVkLmlk
ZW50cnVzdHNzbC5jb20xFjAUBgNVBAsMDUlERU5UUlVTVCBJTkMxFjAUBgNVBAoM
DUlERU5UUlVTVCBJTkMxFzAVBgNVBAcMDlNBTFQgTEFLRSBDSVRZMQ0wCwYDVQQI
DARVVEFIMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAMfv32RRW//GXnNRiJAa7oMzKErpKb+AzWOqKaIw1kLwIcRfCZl6ZFVEHBLz
L0cAHg2WE5+jEXTlGC8Yitt294cUcuzM/UNR2/oTcviIbGSYyAl1NDbWUPIqrnpJ
K/QEMEcV3r2VSGHzgyhBBLrR51CapDYpy1beg7M4oi8535H4waxyTlvrx7YJ5ZnB
0SZNfmAv2UO2WObuFVQP5j+frotJ496ireXydhpseKxG/LZKiAQpHXRNMMu22rwz
Wun6wXTQ+rBNHaeLB00Pnd3GrTsdkg5KRqFVyh8+wa0a9Mvptj1PXMjiyb2TLdfd
fHmmxC1ueYfFf2bny4Bi/Urm7cMCAwEAAaOCBCgwggQkMA4GA1UdDwEB/wQEAwIF
oDCCAicGA1UdIASCAh4wggIaMIIBCwYKYIZIAYb5LwAGAzCB/DBABggrBgEFBQcC
ARY0aHR0cHM6Ly9zZWN1cmUuaWRlbnRydXN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9s
aWN5L3RzLzCBtwYIKwYBBQUHAgIwgaoagadUaGlzIFRydXN0SUQgU2VydmVyIENl
cnRpZmljYXRlIGhhcyBiZWVuIGlzc3VlZCBpbiBhY2NvcmRhbmNlIHdpdGggSWRl
blRydXN0J3MgVHJ1c3RJRCBDZXJ0aWZpY2F0ZSBQb2xpY3kgZm91bmQgYXQgaHR0
cHM6Ly9zZWN1cmUuaWRlbnRydXN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L3Rz
LzCCAQcGBmeBDAECAjCB/DBABggrBgEFBQcCARY0aHR0cHM6Ly9zZWN1cmUuaWRl
bnRydXN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L3RzLzCBtwYIKwYBBQUHAgIw
gaoagadUaGlzIFRydXN0SUQgU2VydmVyIENlcnRpZmljYXRlIGhhcyBiZWVuIGlz
c3VlZCBpbiBhY2NvcmRhbmNlIHdpdGggSWRlblRydXN0J3MgVHJ1c3RJRCBDZXJ0
aWZpY2F0ZSBQb2xpY3kgZm91bmQgYXQgaHR0cHM6Ly9zZWN1cmUuaWRlbnRydXN0
LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L3RzLzAdBgNVHQ4EFgQUcXFUZ6wayp6G
GAd+34JhzuVAv8MwgeYGA1UdHwSB3jCB2zA3oDWgM4YxaHR0cDovL2NybC5pZGVu
dHJ1c3QuY29tL3RydXN0aWQvdHJ1c3RpZGNhYTUxLmNybDCBn6CBnKCBmYaBlmxk
YXA6Ly9sZGFwLmlkZW50cnVzdC5jb20vY249VHJ1c3RJRCUyMFNlcnZlciUyMENB
JTIwQTUxLG91PVRydXN0SUQlMjBTZXJ2ZXIsbz1EaWdpdGFsJTIwU2lnbmF0dXJl
JTIwVHJ1c3QlMjBDby4sYz1VUz9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0O2Jp
bmFyeTB6BggrBgEFBQcBAQRuMGwwJQYIKwYBBQUHMAGGGWh0dHA6Ly9vY3NwLmlk
ZW50cnVzdC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9hcHBzLklkZW5UcnVzdC5j
b20vcm9vdHMvaWRlbnRydXN0dHJ1c3RpZHNzbC5wN2MwHQYDVR0lBBYwFAYIKwYB
BQUHAwEGCCsGAQUFBwMCMB8GA1UdIwQYMBaAFBrSOtPUiKDLDl9SWcXcTo5OyAXW
MCMGA1UdEQQcMBqCGGV4cGlyZWQuaWRlbnRydXN0c3NsLmNvbTANBgkqhkiG9w0B
AQUFAAOCAQEArqD5svgbZCYiApfe5qAKXh96lRfJ1VWO335ZvHWsO6h/aIP2P9nt
CZ+wmP2M/EYOgteDgYIzJL1AAQbV/VNhX9kLcASWa5f63+sdmK9cotLwjkcSxCeb
a5bFyEpLQWgJLlMoHu2Kj2KHONbzXU2xN3E3dCVFbPVUBswCsPspoMr1JY9k1KLl
QDI8IWBbGiJvKcwifWXQ+g2l+NZjG4J0VZ/dwD9XsYqRBCb/1U/vCm+5H2sZ432H
JKwzKO81YBVCz/BVX3QWo4sPfTop3LEfVRVdDSBsXGmMqbLp2bTbKKuQ0fMF1g/o
vmsS6wZVxsSSna7VkmXdoLZDcf7Dv+yGEg==
-----END CERTIFICATE-----`)
// A self-signed cert
var selfSignedCert = []byte(`-----BEGIN CERTIFICATE-----
MIIERTCCAy2gAwIBAgIJAORAsvx6MZO7MA0GCSqGSIb3DQEBBQUAMHQxCzAJBgNV
BAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEXMBUG
A1UEChMOQ2xvdWRGbGFyZSBMTEMxETAPBgNVBAsTCFNlY3VyaXR5MRQwEgYDVQQD
Ewt0ZXN0c3NsLmxvbDAeFw0xNDA0MDQyMjM4MzhaFw0yNDA0MDEyMjM4MzhaMHQx
CzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNj
bzEXMBUGA1UEChMOQ2xvdWRGbGFyZSBMTEMxETAPBgNVBAsTCFNlY3VyaXR5MRQw
EgYDVQQDEwt0ZXN0c3NsLmxvbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAMKNLxpsnT37jSYkP9LVjw050Nmt1YMcEPwLe8zGUr8QzTWQ194Z9Ik/qYS0
UpQlx7+8UBoCanDTYuNKarHhmj4nZp+gc3mWWlaJKRnCJZ+Ru18x2lg9BzG4MwPQ
63ve0WxZ69/6J3lx53ertDgcD7S4v71BaeE10miBeJLK3JkV6fgGGfGRAGwU9vfm
OBbPTAw2SRdB1AaYTHaT4ANwUI7vvkIPrNuneTjOqlN9DAroUNIkXhV+fSmncRxi
RCAfP8/4BZdZ9C4TTKUpdAVUe1LUcHygK2f3YtOx8qJLCRMTRMYccSI1Y1idhX1s
SKIDDrOuELb+pGgno5PCe6i6MWcCAwEAAaOB2TCB1jAdBgNVHQ4EFgQUCkxuIVbR
+I8Z0A547Xj1R57ceXUwgaYGA1UdIwSBnjCBm4AUCkxuIVbR+I8Z0A547Xj1R57c
eXWheKR2MHQxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNU2Fu
IEZyYW5jaXNjbzEXMBUGA1UEChMOQ2xvdWRGbGFyZSBMTEMxETAPBgNVBAsTCFNl
Y3VyaXR5MRQwEgYDVQQDEwt0ZXN0c3NsLmxvbIIJAORAsvx6MZO7MAwGA1UdEwQF
MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKFaOjVRXCNsOznpZe0478mIFK6mNwwi
ZrLcrEUZ0FIOcPwsnQXd/HmrR4MVj3z3U62mE6qFo+07yJnnXdKBJ9ThjmNu6c4S
dk2xPbKTuACF7UhMgPlac0tEp/KSJTaMcjl23H+ol80LZ/t1113XSAZYHWsAgTjC
905kp66Gcq7c+GBgrBqR4e6Z2GYCeAk5aMy5f5s90teW2bIZE0hG1mFz1e25l9lI
SkAp0gZusX4yxqoSBqKmKXBkjrW5vkKJZjP51c7fuhfuAyNfxZF4Cz9SS0YSG8eh
H5kVbpLP+eSYMqF110qqjAo4tkgBquF6IppA+HQ66DN64+TeiXb3f2Y=
-----END CERTIFICATE-----`)
// An expired bundle
var expiredBundlePEM = []byte(`-----BEGIN CERTIFICATE-----
MIIEezCCAmOgAwIBAgIUUNg8o/9IQGSH6PBBxo06zIJEcaAwDQYJKoZIhvcNAQEN
BQAwgYwxCzAJBgNVBAYTAlVTMRMwEQYDVQQKEwpDbG91ZEZsYXJlMRwwGgYDVQQL
ExNTeXN0ZW1zIEVuZ2luZWVyaW5nMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRMw
EQYDVQQIEwpDYWxpZm9ybmlhMR0wGwYDVQQDExRjbG91ZGZsYXJlLWludGVyLmNv
bTAeFw0xNzA1MjIyMjEzMDBaFw0yMjA1MjMwNDEzMDBaMIGLMQswCQYDVQQGEwJV
UzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzET
MBEGA1UEChMKQ2xvdWRGbGFyZTEcMBoGA1UECxMTU3lzdGVtcyBFbmdpbmVlcmlu
ZzEcMBoGA1UEAxMTY2xvdWRmbGFyZS1sZWFmLmNvbTBZMBMGByqGSM49AgEGCCqG
SM49AwEHA0IABIxG/fG9y/gjlAXvB77beERLbBooN98FGFAxVUA5IglylvgmfNxU
mI8mM2Uw9tzOLm9vORAraSSM4/6iSpCJreCjgZ4wgZswEwYDVR0lBAwwCgYIKwYB
BQUHAwEwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUqc1Wy6iYDBNjgFSn8WtaWXd3
yK4wHwYDVR0jBBgwFoAUiGC6GKR3uEEEG9Xvd1HCWxS6ID8wNgYDVR0RBC8wLYIT
Y2xvdWRmbGFyZS1sZWFmLmNvbYIWd3d3Y2xvdWRmbGFyZS1sZWFmLmNvbTANBgkq
hkiG9w0BAQ0FAAOCAgEAFH0prS82UElynKi7ik9gmTyrKz/YWTdXe9tGLPKSr88I
vBKMr1TuY13qTYKybTcUq3HTvJEvAyih7VbGQFqPnNpBE6DdE/M+Cfxo0iwM8e+C
49APOcMZKrddNnAfhmQqJuFJUCvHmKQ8p8VXfUm3q6qIwqwKTyubmGvO6b3JUtoD
MDOX4GZdYuIp7Q5jNWXDxw0k4ycaE8CZuRpOjVZ75X8OzwRG+ZFkAZlvxs4APpRr
n8gQ9U5cy00uLzwCgsNiJbweElcaBAEkurBZzLtXMd3sQKAH5kyqjeZTATb547tq
c0ykdcsf6ghBbGmNF+Bg3U7vY6ddep6sj5ifxCdAv9xqDCoKvG2JXYM2N56lFNWv
RJLIuB2nru/QeV0Rpq+UADfj3jkfxWk3H7YoOoYQTXllZ6aIfiOb9MqVYQUx1+G2
WV9sG10aRX+nYwvmddsUrkiKLgPhzE7Exn0f+dyN+FROsInniqNO7LC56ICJt72C
DPLLg0SQaaXjfEw3hnaf3YOHhP+opl9Q3HfVbe3ftJD1pp5BsK5S/hD/vegQZ3NL
MhBvsWX+HW3OuvGbbnLruqcRRH3LA/Pm+8IImAbdFXntcuuuQCb66YT/Gh0bkpoD
8R5sjAanl/EYiQIds4ZUuRrec+90ieceKM+P/b9wwLXHW2/o2s1evg2dGcJ97DY=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEfTCCA+agAwIBAgIUFalofeaKAEmnWkBXWu4lkwmmh3IwDQYJKoZIhvcNAQEF
BQAwfTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM
DVNhbiBGcmFuY2lzY28xEzARBgNVBAoMCkNsb3VkRmxhcmUxFDASBgNVBAsMC0RF
Vl9URVNUSU5HMRYwFAYDVQQDDA1DRlNTTF9URVNUX0NBMB4XDTE2MDIxODAxMTIw
MFoXDTE2MDIxODAxMTIwMVowgYwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxp
Zm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRMwEQYDVQQKEwpDbG91ZEZs
YXJlMRwwGgYDVQQLExNTeXN0ZW1zIEVuZ2luZWVyaW5nMR0wGwYDVQQDExRjbG91
ZGZsYXJlLWludGVyLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
AOUKdX6+PSxU/LxKocsCUj7HCc+FaDOPZV68Po3PVm7UF5DmbnLgJYJ/4aZEZM/v
5r8LnXQXDqumYicHQ2DHHBDasLTx8m0KeKOUYf9WMQ8gdjmVFoCiZwzxGDHok66/
0Glkkqmv2nJQxXncl5ZFta4sfmcQx3KT02l61LaBbG3j8PbRCWEr+0eRE6twuYRR
13AgZ3ATwnMjzxzvsW67qmAy0cq+XgYYfTK9vhPs+8J0fxXa0Iftu3yuhd30xLIV
XLu45GR+i6KnsSxVERSaVxjkS+lHXjUpdtmqI5CK6wn67vqYRRA2TzAJHX8Jb+KL
2/UEo5WNfAJ8S0heODQA8nHVU1JIfpegOlQRMv55DgnQUv1c1uwO5hqvv7MPQ3X/
m9Kjccs1FBH1/SVuzKyxYEQ34LErX3HI+6avbVnRtTR/UHkfnZVIXSrcjUm73BGj
33hrtiKl0ZyZnaUKGZPuvebOUFNiXemhTbqrfi/zAb1Tsm/h+xkn5EZ5sMj5NHdA
bpih3TqX2gRhnFZcFjtJM6zzC5O7eG5Kdqf8iladXTXtWxzrUPkb5CupzFl1dyS3
dqdkoIXvkmlScnu+6jBOaYeVvwogxr2Y69y4Zfg/qbPyBOLZquX9ovbuSP1DQmC/
/LV5t7YHHY/1MXr5U0MMvcn+9JWUV6ou3at4AgEqfK0vAgMBAAGjZjBkMA4GA1Ud
DwEB/wQEAwICBDASBgNVHRMBAf8ECDAGAQH/AgEBMB0GA1UdDgQWBBSIYLoYpHe4
QQQb1e93UcJbFLogPzAfBgNVHSMEGDAWgBS4Xu+uZ1C31vMH5Wq+VbNnOg2SPjAN
BgkqhkiG9w0BAQUFAAOBgQAnGnLG3r4g+0bLkeeh1Y71pL0Ui1LnvCA1v+yVDCd0
G9pj7cnHHXjnp4Pic6pP9uwxBAiUC6rzjpKrm1ULYMoQPLAYmwJiz+8yiE5vpMCA
Ov3LFPDNAbGF2wavwpCVolnVgHzPSFTEXN53DdXdVhcQ207P+zWNCNDF4Q33WSfm
Dw==
-----BEGIN CERTIFICATE-----
MIIEezCCAmOgAwIBAgIUUNg8o/9IQGSH6PBBxo06zIJEcaAwDQYJKoZIhvcNAQEN
BQAwgYwxCzAJBgNVBAYTAlVTMRMwEQYDVQQKEwpDbG91ZEZsYXJlMRwwGgYDVQQL
ExNTeXN0ZW1zIEVuZ2luZWVyaW5nMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRMw
EQYDVQQIEwpDYWxpZm9ybmlhMR0wGwYDVQQDExRjbG91ZGZsYXJlLWludGVyLmNv
bTAeFw0xNzA1MjIyMjEzMDBaFw0yMjA1MjMwNDEzMDBaMIGLMQswCQYDVQQGEwJV
UzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzET
MBEGA1UEChMKQ2xvdWRGbGFyZTEcMBoGA1UECxMTU3lzdGVtcyBFbmdpbmVlcmlu
ZzEcMBoGA1UEAxMTY2xvdWRmbGFyZS1sZWFmLmNvbTBZMBMGByqGSM49AgEGCCqG
SM49AwEHA0IABIxG/fG9y/gjlAXvB77beERLbBooN98FGFAxVUA5IglylvgmfNxU
mI8mM2Uw9tzOLm9vORAraSSM4/6iSpCJreCjgZ4wgZswEwYDVR0lBAwwCgYIKwYB
BQUHAwEwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUqc1Wy6iYDBNjgFSn8WtaWXd3
yK4wHwYDVR0jBBgwFoAUiGC6GKR3uEEEG9Xvd1HCWxS6ID8wNgYDVR0RBC8wLYIT
Y2xvdWRmbGFyZS1sZWFmLmNvbYIWd3d3Y2xvdWRmbGFyZS1sZWFmLmNvbTANBgkq
hkiG9w0BAQ0FAAOCAgEAFH0prS82UElynKi7ik9gmTyrKz/YWTdXe9tGLPKSr88I
vBKMr1TuY13qTYKybTcUq3HTvJEvAyih7VbGQFqPnNpBE6DdE/M+Cfxo0iwM8e+C
49APOcMZKrddNnAfhmQqJuFJUCvHmKQ8p8VXfUm3q6qIwqwKTyubmGvO6b3JUtoD
MDOX4GZdYuIp7Q5jNWXDxw0k4ycaE8CZuRpOjVZ75X8OzwRG+ZFkAZlvxs4APpRr
n8gQ9U5cy00uLzwCgsNiJbweElcaBAEkurBZzLtXMd3sQKAH5kyqjeZTATb547tq
c0ykdcsf6ghBbGmNF+Bg3U7vY6ddep6sj5ifxCdAv9xqDCoKvG2JXYM2N56lFNWv
RJLIuB2nru/QeV0Rpq+UADfj3jkfxWk3H7YoOoYQTXllZ6aIfiOb9MqVYQUx1+G2
WV9sG10aRX+nYwvmddsUrkiKLgPhzE7Exn0f+dyN+FROsInniqNO7LC56ICJt72C
DPLLg0SQaaXjfEw3hnaf3YOHhP+opl9Q3HfVbe3ftJD1pp5BsK5S/hD/vegQZ3NL
MhBvsWX+HW3OuvGbbnLruqcRRH3LA/Pm+8IImAbdFXntcuuuQCb66YT/Gh0bkpoD
8R5sjAanl/EYiQIds4ZUuRrec+90ieceKM+P/b9wwLXHW2/o2s1evg2dGcJ97DY=
-----END CERTIFICATE-----`)
|