Skip to content

Commit 60d5479

Browse files
shigekitwifkak
authored andcommitted
Check certificate profiles and its validity period (#306)
This makes the following checks to the leaf certificate if it has - a valid public key corresponding to its private key - a domain in CN or SubjectAltname specified in URLSet.Sign.Domain - a validity period within 90 days according to SXG cert requirements
1 parent fc3bf6f commit 60d5479

19 files changed

+426
-2
lines changed

cmd/amppkg/main.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,18 @@ func main() {
9393
if !(*flagDevelopment || *flagInvalidCert || util.CanSignHttpExchanges(certs[0])) {
9494
die("cert is missing CanSignHttpExchanges extension")
9595
}
96-
// TODO(twifkak): Verify that certs[0] covers all the signing domains in the config.
9796

9897
key, err := util.ParsePrivateKey(keyPem)
9998
if err != nil {
10099
die(errors.Wrapf(err, "parsing %s", config.KeyFile))
101100
}
102-
// TODO(twifkak): Verify that key matches certs[0].
101+
102+
for _, urlSet := range config.URLSet {
103+
domain := urlSet.Sign.Domain
104+
if err := util.CheckCertificate(certs[0], key, domain, time.Now()); err != nil {
105+
die(errors.Wrapf(err, "checking %s", config.CertFile))
106+
}
107+
}
103108

104109
validityMap, err := validitymap.New()
105110
if err != nil {

packager/testing/testing.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,48 @@ var Key = func() crypto.PrivateKey {
4242
return key
4343
}()
4444

45+
// 90 days cert of amppackageexample.com and www.amppackageexample.com in SAN
46+
var B3Certs = func() []*x509.Certificate {
47+
certPem, _ := ioutil.ReadFile("../../testdata/b3/fullchain.cert")
48+
certs, _ := signedexchange.ParseCertificates(certPem)
49+
return certs
50+
}()
51+
52+
// Private key of B3Certs
53+
var B3Key = func() crypto.PrivateKey {
54+
keyPem, _ := ioutil.ReadFile("../../testdata/b3/server.privkey")
55+
key, _ := util.ParsePrivateKey(keyPem)
56+
return key
57+
}()
58+
59+
// 90 days cert of amppackageexample2.com and www.amppackageexample2.com in SAN
60+
var B3Certs2 = func() []*x509.Certificate {
61+
certPem, _ := ioutil.ReadFile("../../testdata/b3/fullchain2.cert")
62+
certs, _ := signedexchange.ParseCertificates(certPem)
63+
return certs
64+
}()
65+
66+
// Private key of B3Certs2
67+
var B3Key2 = func() crypto.PrivateKey {
68+
keyPem, _ := ioutil.ReadFile("../../testdata/b3/server2.privkey")
69+
key, _ := util.ParsePrivateKey(keyPem)
70+
return key
71+
}()
72+
73+
// 91 days cert from B3Key
74+
var B3Certs91Days = func() []*x509.Certificate {
75+
certPem, _ := ioutil.ReadFile("../../testdata/b3/fullchain_91days.cert")
76+
certs, _ := signedexchange.ParseCertificates(certPem)
77+
return certs
78+
}()
79+
80+
// secp521r1 private key
81+
var B3KeyP521 = func() crypto.PrivateKey {
82+
keyPem, _ := ioutil.ReadFile("../../testdata/b3/server_p521.privkey")
83+
key, _ := util.ParsePrivateKey(keyPem)
84+
return key
85+
}()
86+
4587
// The URL path component corresponding to the cert's sha-256.
4688
var CertName = util.CertName(Certs[0])
4789

packager/util/util.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,26 @@ package util
1717
import (
1818
"bytes"
1919
"crypto"
20+
"crypto/ecdsa"
2021
"crypto/sha256"
2122
"crypto/x509"
2223
"encoding/asn1"
2324
"encoding/base64"
2425
"encoding/pem"
26+
"time"
2527

2628
"github.com/WICG/webpackage/go/signedexchange"
2729
"github.com/pkg/errors"
2830
)
2931

3032
const CertURLPrefix = "/amppkg/cert"
3133

34+
// https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html#cross-origin-cert-req
35+
// Clients MUST reject certificates with this extension that were issued after 2019-05-01 and have a Validity Period longer than 90 days.
36+
// After 2019-08-01, clients MUST reject all certificates with this extension that have a Validity Period longer than 90 days.
37+
var start90DayGracePeriod = time.Date(2019, time.May, 1, 0, 0, 0, 0, time.UTC)
38+
var end90DayGracePeriod = time.Date(2019, time.August, 1, 0, 0, 0, 0, time.UTC)
39+
3240
// CertName returns the basename for the given cert, as served by this
3341
// packager's cert cache. Should be stable and unique (e.g.
3442
// content-addressing). Clients should url.PathEscape this, just in case its
@@ -76,3 +84,27 @@ func CanSignHttpExchanges(cert *x509.Certificate) bool {
7684
}
7785
return false
7886
}
87+
88+
func CheckCertificate(cert *x509.Certificate, priv crypto.PrivateKey, domain string, now time.Time) error {
89+
certPubKey := cert.PublicKey.(*ecdsa.PublicKey)
90+
pubKey := priv.(*ecdsa.PrivateKey).PublicKey
91+
if certPubKey.Curve != pubKey.Curve {
92+
return errors.New("PublicKey.Curve not match")
93+
}
94+
if certPubKey.X.Cmp(pubKey.X) != 0 {
95+
return errors.New("PublicKey.X not match")
96+
}
97+
if certPubKey.Y.Cmp(pubKey.Y) != 0 {
98+
return errors.New("PublicKey.Y not match")
99+
}
100+
if err := cert.VerifyHostname(domain); err != nil {
101+
return err
102+
}
103+
// TODO: remove issue date and current time check after 2019-08-01
104+
if cert.NotBefore.After(start90DayGracePeriod) || now.After(end90DayGracePeriod) {
105+
if cert.NotBefore.AddDate(0,0,90).Before(cert.NotAfter) {
106+
return errors.New("Certificate MUST have a Validity Period no greater than 90 days")
107+
}
108+
}
109+
return nil
110+
}

packager/util/util_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,21 @@ import (
44
"crypto/ecdsa"
55
"crypto/elliptic"
66
"testing"
7+
"time"
78

89
pkgt "github.com/ampproject/amppackager/packager/testing"
910
"github.com/ampproject/amppackager/packager/util"
1011
"github.com/stretchr/testify/assert"
1112
"github.com/stretchr/testify/require"
1213
)
1314

15+
func errorFrom(err error) string {
16+
if err == nil {
17+
return ""
18+
}
19+
return err.Error()
20+
}
21+
1422
func TestCertName(t *testing.T) {
1523
assert.Equal(t, "PJ1IwfP1igOlJd2oTUVs2mj4dWIZcOWHMk5jfJYS2Qc", util.CertName(pkgt.Certs[0]))
1624
}
@@ -27,3 +35,42 @@ func TestCanSignHttpExchanges(t *testing.T) {
2735
// CA node does not.
2836
assert.False(t, util.CanSignHttpExchanges(pkgt.Certs[1]))
2937
}
38+
39+
func TestParseCertificate(t *testing.T) {
40+
assert.Nil(t, util.CheckCertificate(pkgt.B3Certs[0], pkgt.B3Key, "amppackageexample.com", time.Now()))
41+
}
42+
43+
func TestParseCertificateSubjectAltName(t *testing.T) {
44+
assert.Nil(t, util.CheckCertificate(pkgt.B3Certs[0], pkgt.B3Key, "www.amppackageexample.com", time.Now()))
45+
}
46+
47+
func TestParseCertificateNotMatchX(t *testing.T) {
48+
assert.Contains(t, errorFrom(util.CheckCertificate(pkgt.B3Certs[0],
49+
pkgt.B3Key2, "amppackageexample.com", time.Now())), "PublicKey.X not match")
50+
}
51+
52+
func TestParseCertificateNotMatchCurve(t *testing.T) {
53+
assert.Contains(t, errorFrom(util.CheckCertificate(pkgt.B3Certs[0],
54+
pkgt.B3KeyP521, "amppackageexample.com", time.Now())), "PublicKey.Curve not match")
55+
}
56+
57+
func TestParseCertificateNotMatchDomain(t *testing.T) {
58+
assert.Contains(t, errorFrom(util.CheckCertificate(pkgt.B3Certs2[0],
59+
pkgt.B3Key2, "amppackageexample.com", time.Now())), "x509: certificate is valid for amppackageexample2.com, www.amppackageexample2.com, not amppackageexample.com")
60+
}
61+
62+
func TestParse91DaysCertificate(t *testing.T) {
63+
assert.Contains(t, errorFrom(util.CheckCertificate(pkgt.B3Certs91Days[0],
64+
pkgt.B3Key, "amppackageexample.com", time.Now())), "Certificate MUST have a Validity Period no greater than 90 days")
65+
}
66+
67+
func TestParseCertificateIssuedBeforeMay1InGarcePeriod(t *testing.T) {
68+
now := time.Date(2019, time.July, 31, 0, 0, 0, 0, time.UTC)
69+
assert.Nil(t, util.CheckCertificate(pkgt.Certs[0], pkgt.Key, "amppackageexample.com", now))
70+
}
71+
72+
func TestParseCertificateIssuedBeforeMay1AfterGracePeriod(t *testing.T) {
73+
now := time.Date(2019, time.August, 1, 0, 0, 0, 1, time.UTC)
74+
assert.Contains(t, errorFrom(util.CheckCertificate(pkgt.Certs[0],
75+
pkgt.Key, "amppackageexample.com", now)), "Certificate MUST have a Validity Period no greater than 90 days")
76+
}

testdata/b3/README.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Test certificates for b3
2+
3+
This is example certificates for tests built under the constraints set by `v=b3` except having AIA and SCT extension.
4+
5+
To generate:
6+
7+
CA private key and cert,
8+
```
9+
$ openssl genrsa -out ca.privkey 2048
10+
$ openssl req -x509 -new -nodes -key ca.privkey -sha256 -days 1825 -out ca.cert -subj '/C=US/ST=California/O=Google LLC/CN=Fake CA'
11+
```
12+
13+
server.privkey and server.cert of amppackageexample.com and www.amppackageexample.com,
14+
```
15+
$ openssl ecparam -out server.privkey -name prime256v1 -genkey
16+
$ openssl req -new -sha256 -key server.privkey -out server.csr -subj /CN=amppackageexample.com
17+
$ openssl x509 -req -in server.csr -CA ca.cert -CAkey ca.privkey -CAcreateserial -out server.cert -days 90 -extfile <(echo -e "subjectAltName = DNS:amppackageexample.com,DNS:www.amppackageexample.com\n1.3.6.1.4.1.11129.2.1.22 = ASN1:NULL")
18+
$ cat server.cert ca.cert > fullchain.cert
19+
20+
server2.privkey and server2.cert of amppackageexample2.com and www.amppackageexample2.com,
21+
```
22+
$ openssl ecparam -out server2.privkey -name prime256v1 -genkey
23+
$ openssl req -new -sha256 -key server2.privkey -out server2.csr -subj /CN=amppackageexample2.com
24+
$ openssl x509 -req -in server2.csr -CA ca.cert -CAkey ca.privkey -CAcreateserial -out server2.cert -days 90 -extfile <(echo -e "subjectAltName = DNS:amppackageexample2.com,DNS:www.amppackageexample2.com\n1.3.6.1.4.1.11129.2.1.22 = ASN1:NULL")
25+
$ cat server2.cert ca.cert > fullchain2.cert
26+
```
27+
28+
and others
29+
```
30+
$ openssl x509 -req -in server.csr -CA ca.cert -CAkey ca.privkey -CAcreateserial -out server_91days.cert -days 91 -extfile <(echo -e "subjectAltName = DNS:amppackageexample.com,DNS:www.amppackageexample.com\n1.3.6.1.4.1.11129.2.1.22 = ASN1:NULL")
31+
$ cat server_91days.cert ca.cert > fullchain_91days.cert
32+
$ openssl ecparam -out server_p521.privkey -name secp521r1 -genkey
33+
```
34+
35+
### Appendix
36+
37+
<!--
38+
TODO(twifkak): Update this to add AIA for OCSP.
39+
https://www.feistyduck.com/library/openssl-cookbook/online/ch-openssl.html
40+
https://github.com/grimm-co/GOCSP-responder
41+
https://github.com/OpenVPN/easy-rsa
42+
https://gist.github.com/NoMan2000/06fffaca2ea710175cbcdd1a933c44af
43+
-->
44+
45+
See some tutorials:
46+
- https://github.com/WICG/webpackage/tree/master/go/signedexchange
47+
- https://deliciousbrains.com/ssl-certificate-authority-for-local-https-development/
48+
- https://github.com/jmmcatee/cracklord/wiki/Creating-Certificate-Authentication-From-Scratch-OpenSSL
49+
- https://gist.github.com/Soarez/9688998
50+
- https://jamielinux.com/docs/openssl-certificate-authority/online-certificate-status-protocol.html

testdata/b3/ca.cert

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIDaDCCAlCgAwIBAgIJAKRDrJBUupZAMA0GCSqGSIb3DQEBCwUAMEkxCzAJBgNV
3+
BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRMwEQYDVQQKDApHb29nbGUgTExD
4+
MRAwDgYDVQQDDAdGYWtlIENBMB4XDTE4MDgyOTIxMjIyOVoXDTIzMDgyODIxMjIy
5+
OVowSTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEzARBgNVBAoM
6+
Ckdvb2dsZSBMTEMxEDAOBgNVBAMMB0Zha2UgQ0EwggEiMA0GCSqGSIb3DQEBAQUA
7+
A4IBDwAwggEKAoIBAQC52bjEZwQIt5pIZY712P6nbQOoRGKmalU6SksHjhVx8x93
8+
58Fjs+z1S1xm+HwU8LDj82wapj2/GZbLgk6wiYeSF17a4cKbdOfZUqQiQpQfciAB
9+
S3sd2ZG0YghR/VdTHa3mH56lX90Z/3pq0KlwIDk1U/PpKYaWwC1Ywpj1COEJ9Omd
10+
TjcoPQ1nEc1vKdlyjlAvDYqKptrK2grGykvu0Rh2ZeJ99YSSYknh6zx6U3FWtKlm
11+
PgMjSWO2gtpbMLPI3Uehde0b3Bq8JntjPvbh8gLoGaOEsvvDgTfFRpRkNqMAjLVf
12+
z/zol9CpBdggg4Fyj9J0CGjM9f1ZBhXLmtoxkAQjAgMBAAGjUzBRMB0GA1UdDgQW
13+
BBSiY4BoP6E4Rx6tSi0iXDHU5D3vlTAfBgNVHSMEGDAWgBSiY4BoP6E4Rx6tSi0i
14+
XDHU5D3vlTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCG9ARQ
15+
S1tOW0PVuJ5H4WU0hRmDn5oUkEu9DzD1WoGGTN6CCM0AfLBo0ARwqntvSNtERIA6
16+
BfVSaeqO6WNrvGDLwi+YcUlTxyGLsGlDz/xeQ7WIVGlbhyTJYH5B1yliRyZN4M2E
17+
hIqWqBMSvtqCnMMJEr/0BsigDIEiEUXwsc6tC77HudXxV0AVs4MLBz3iowkeZMB6
18+
qZAVRKCmVptIsPyP+eO3vIIWi0y7eQx/8WOpW52CYj9MhhDa9/IcJLIRQIOe7fRn
19+
1tL/h+aRMq7ywOrwbO/s2HQ7kG/jFIRj0QMxeCExTzPhND22EVvVisfocXS91QuL
20+
PjZuIWmKwDo/Vvau
21+
-----END CERTIFICATE-----

testdata/b3/ca.privkey

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
-----BEGIN RSA PRIVATE KEY-----
2+
MIIEowIBAAKCAQEAudm4xGcECLeaSGWO9dj+p20DqERipmpVOkpLB44VcfMfd+fB
3+
Y7Ps9UtcZvh8FPCw4/NsGqY9vxmWy4JOsImHkhde2uHCm3Tn2VKkIkKUH3IgAUt7
4+
HdmRtGIIUf1XUx2t5h+epV/dGf96atCpcCA5NVPz6SmGlsAtWMKY9QjhCfTpnU43
5+
KD0NZxHNbynZco5QLw2KiqbaytoKxspL7tEYdmXiffWEkmJJ4es8elNxVrSpZj4D
6+
I0ljtoLaWzCzyN1HoXXtG9wavCZ7Yz724fIC6BmjhLL7w4E3xUaUZDajAIy1X8/8
7+
6JfQqQXYIIOBco/SdAhozPX9WQYVy5raMZAEIwIDAQABAoIBACHsv1CCqXbZ5PzQ
8+
JQ91g86WFLPTf9p20IXqZ9XCNuHtClJ96IxFnLyN/BkDxMqhwPhrR9F5hQ3sIt2V
9+
NL3+7NNbFsKHsVllNqkx76odUyKGV5dE6v1g6LrvpispPpZ6dXLrVK9FV3vWaccz
10+
vaotB6RXZc+q99luzRhFtVwNOd7yGQWkn1sKO1i/QWiARdob/inKArbNl3W0GtJ0
11+
kIjQNm28JFpzTxUbjoWOOUoH4B8PyOS+k6+ByjJDBhLiinl3I7M+g6LWqr2cdam8
12+
xyoHHyUtYM1DbCoPJKDtJeJkxNP9TZTJLLq/lqRjm14kvcIHvQxFSZF/NqJivurq
13+
LYtghDkCgYEA7SC1ot2PjkZ2MZNQQsT5HrAwqqfogb9AvQ2HSkFN71LGZQcfxhNS
14+
chg1/MH3R9k95xDPSFc2T5DxEBUFaImeGhPNnm1YzHJbixZgBu2G6DAEks95qtYf
15+
bDWRFG60ulaJAeveVYxhnoXARc9NMPAbek6VgFi1QWFY+M/VTC3cve8CgYEAyKRH
16+
J6eUurQZti9mUwbSPWB41+hi7KFL3qC618qOf0XDnDlGvhSxkMLdnICMDOxg6U/b
17+
0G4Zlyb6JbyZ5jiDpvcAbqqGsickmI8SJeKbp9zQT0mELuRdx12YuMi0aA81gaIm
18+
ekYDiQp28enO778s033ikrYwVu2yLakrFayakQ0CgYEAnc8Z8nSfGCF+gUm3rWfn
19+
HuxExx4Nl2OPkwGQ2vMRCce9rviJxcmQIcxJCZiQl+lU0BUYzdz0kQk11O0Yd1S2
20+
ukYZnmjJIu6sS6ktaQ7krFtgf8/B+dacfOg9UCrI7gWvEm9FvQs64EPFDPCEP6Bb
21+
uQ7ZYdwnbIZ7rsKqAhO3h1MCgYBfGwejc1sbmO0rH5K4Pl5/u2/sn/nsQpStBbEr
22+
QpeDGrWbIsc2qKZ2gPf9DC3WnmFdln4ScW3t6QrfwmOM7jLxfNmWm3xXjBhbvE2U
23+
6bJwwkl3m9htRdByBRq0VGa3gKYTOaJViUR5vB0flH2DxTHhWiWA9504R1mTLUH/
24+
9x4ZLQKBgE039cFcqazKgUrhGfnHo6DKMYv9tLfpwBrfGrjS5eL9HzwCjqflH7Ql
25+
rN/8D4hNeT+lU9m8gAZkf7a/9Atz+V97gIKRzLg8ShHPg4lcjHaAK35CRSrNc+i0
26+
Hf1WpUKryO9CCzqsmO1Z+hxLVC1rSYJ2C8TRI3FMf3Gay/IzUUXF
27+
-----END RSA PRIVATE KEY-----

testdata/b3/ca.srl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
E9E246FA1A4FB5BF

testdata/b3/fullchain.cert

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIICcjCCAVqgAwIBAgIJAOniRvoaT7W9MA0GCSqGSIb3DQEBCwUAMEkxCzAJBgNV
3+
BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRMwEQYDVQQKDApHb29nbGUgTExD
4+
MRAwDgYDVQQDDAdGYWtlIENBMB4XDTE5MDUwOTA1NDMzMloXDTE5MDgwNzA1NDMz
5+
MlowIDEeMBwGA1UEAwwVYW1wcGFja2FnZWV4YW1wbGUuY29tMFkwEwYHKoZIzj0C
6+
AQYIKoZIzj0DAQcDQgAEOFjcTTfGjzqRM1fZ+vzaDcOwQcO0enVPHYqe6c5pPEux
7+
3DYBUbPOkLuyzCwUpC+kxu1a3GcvdO4yyVT56GvEfqNRME8wOwYDVR0RBDQwMoIV
8+
YW1wcGFja2FnZWV4YW1wbGUuY29tghl3d3cuYW1wcGFja2FnZWV4YW1wbGUuY29t
9+
MBAGCisGAQQB1nkCARYEAgUAMA0GCSqGSIb3DQEBCwUAA4IBAQA15v5hJEiinNQk
10+
GplWJBYeBSjWMnwfvXqpWYiIw47692+ELBihlmYY+xcAhUbvBty7695LiHRRbJLL
11+
c4QC8EoAePuvrty6vZVZbVc9FUFRKvgQ0n3FzMok/0QTfUNeQbfQBWomxxmlySsD
12+
WwQ3fcRtGRETspcBMrhHorVplSAqAtr41bxe1Wh+RywmJRtG+1/Tp8zU6Py6bkPz
13+
pHkwkkua+ucwhU0xk3Ipe5vZVOSZQofVqDpSuUadrhU6B7fDI+B+nniiyOXplgNx
14+
CVoSy6nrsUb1nAFIDxKxrTrhlHi8oXGR9JvMLf4u+A+0d64SeXkgmYFIc5ftYHlz
15+
BKMgdmFI
16+
-----END CERTIFICATE-----
17+
-----BEGIN CERTIFICATE-----
18+
MIIDaDCCAlCgAwIBAgIJAKRDrJBUupZAMA0GCSqGSIb3DQEBCwUAMEkxCzAJBgNV
19+
BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRMwEQYDVQQKDApHb29nbGUgTExD
20+
MRAwDgYDVQQDDAdGYWtlIENBMB4XDTE4MDgyOTIxMjIyOVoXDTIzMDgyODIxMjIy
21+
OVowSTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEzARBgNVBAoM
22+
Ckdvb2dsZSBMTEMxEDAOBgNVBAMMB0Zha2UgQ0EwggEiMA0GCSqGSIb3DQEBAQUA
23+
A4IBDwAwggEKAoIBAQC52bjEZwQIt5pIZY712P6nbQOoRGKmalU6SksHjhVx8x93
24+
58Fjs+z1S1xm+HwU8LDj82wapj2/GZbLgk6wiYeSF17a4cKbdOfZUqQiQpQfciAB
25+
S3sd2ZG0YghR/VdTHa3mH56lX90Z/3pq0KlwIDk1U/PpKYaWwC1Ywpj1COEJ9Omd
26+
TjcoPQ1nEc1vKdlyjlAvDYqKptrK2grGykvu0Rh2ZeJ99YSSYknh6zx6U3FWtKlm
27+
PgMjSWO2gtpbMLPI3Uehde0b3Bq8JntjPvbh8gLoGaOEsvvDgTfFRpRkNqMAjLVf
28+
z/zol9CpBdggg4Fyj9J0CGjM9f1ZBhXLmtoxkAQjAgMBAAGjUzBRMB0GA1UdDgQW
29+
BBSiY4BoP6E4Rx6tSi0iXDHU5D3vlTAfBgNVHSMEGDAWgBSiY4BoP6E4Rx6tSi0i
30+
XDHU5D3vlTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCG9ARQ
31+
S1tOW0PVuJ5H4WU0hRmDn5oUkEu9DzD1WoGGTN6CCM0AfLBo0ARwqntvSNtERIA6
32+
BfVSaeqO6WNrvGDLwi+YcUlTxyGLsGlDz/xeQ7WIVGlbhyTJYH5B1yliRyZN4M2E
33+
hIqWqBMSvtqCnMMJEr/0BsigDIEiEUXwsc6tC77HudXxV0AVs4MLBz3iowkeZMB6
34+
qZAVRKCmVptIsPyP+eO3vIIWi0y7eQx/8WOpW52CYj9MhhDa9/IcJLIRQIOe7fRn
35+
1tL/h+aRMq7ywOrwbO/s2HQ7kG/jFIRj0QMxeCExTzPhND22EVvVisfocXS91QuL
36+
PjZuIWmKwDo/Vvau
37+
-----END CERTIFICATE-----

testdata/b3/fullchain2.cert

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIICdTCCAV2gAwIBAgIJAOniRvoaT7W+MA0GCSqGSIb3DQEBCwUAMEkxCzAJBgNV
3+
BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRMwEQYDVQQKDApHb29nbGUgTExD
4+
MRAwDgYDVQQDDAdGYWtlIENBMB4XDTE5MDUwOTA1NDQ1MVoXDTE5MDgwNzA1NDQ1
5+
MVowITEfMB0GA1UEAwwWYW1wcGFja2FnZWV4YW1wbGUyLmNvbTBZMBMGByqGSM49
6+
AgEGCCqGSM49AwEHA0IABPrQ/l9HqUGjmupFkJo+dZt6/UoR5sFunT72ZoRc0Nvh
7+
zP+qpvZdTBzkZejExW3xor6iIGowuKKPWOJA976Sj52jUzBRMD0GA1UdEQQ2MDSC
8+
FmFtcHBhY2thZ2VleGFtcGxlMi5jb22CGnd3dy5hbXBwYWNrYWdlZXhhbXBsZTIu
9+
Y29tMBAGCisGAQQB1nkCARYEAgUAMA0GCSqGSIb3DQEBCwUAA4IBAQCmh+Ff+GUC
10+
S/IFh2xLtXcnB+elfr75PwldD91LqRnTYu/DC9tKcfDxKZIwHw0B5gLg362lAdB1
11+
88I8XJrrf8WfH6auCcuhdoCDyNVbbXqsapwTHEaUFZiCVnPt0eJRdau6voZLKGZM
12+
/zEMVUg9qPOSCR5+j2hpmPyFNCUqK6RpNpCKFXf/WJOHphAIqLeFbLJa4kIfIL6b
13+
m/K2Og93H0uVX3j5jgaQncRxX6ZKCje+2MzNvPBZhWJgU+xTDPLPOPeQX+sHj6k6
14+
TjsTgQ9GbpHPuoWc0keW6ulVwN7VW5EfUmM3fvftO2/5hHI6qIVnhrTgto+u+7vH
15+
oDSK9AJC357d
16+
-----END CERTIFICATE-----
17+
-----BEGIN CERTIFICATE-----
18+
MIIDaDCCAlCgAwIBAgIJAKRDrJBUupZAMA0GCSqGSIb3DQEBCwUAMEkxCzAJBgNV
19+
BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRMwEQYDVQQKDApHb29nbGUgTExD
20+
MRAwDgYDVQQDDAdGYWtlIENBMB4XDTE4MDgyOTIxMjIyOVoXDTIzMDgyODIxMjIy
21+
OVowSTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEzARBgNVBAoM
22+
Ckdvb2dsZSBMTEMxEDAOBgNVBAMMB0Zha2UgQ0EwggEiMA0GCSqGSIb3DQEBAQUA
23+
A4IBDwAwggEKAoIBAQC52bjEZwQIt5pIZY712P6nbQOoRGKmalU6SksHjhVx8x93
24+
58Fjs+z1S1xm+HwU8LDj82wapj2/GZbLgk6wiYeSF17a4cKbdOfZUqQiQpQfciAB
25+
S3sd2ZG0YghR/VdTHa3mH56lX90Z/3pq0KlwIDk1U/PpKYaWwC1Ywpj1COEJ9Omd
26+
TjcoPQ1nEc1vKdlyjlAvDYqKptrK2grGykvu0Rh2ZeJ99YSSYknh6zx6U3FWtKlm
27+
PgMjSWO2gtpbMLPI3Uehde0b3Bq8JntjPvbh8gLoGaOEsvvDgTfFRpRkNqMAjLVf
28+
z/zol9CpBdggg4Fyj9J0CGjM9f1ZBhXLmtoxkAQjAgMBAAGjUzBRMB0GA1UdDgQW
29+
BBSiY4BoP6E4Rx6tSi0iXDHU5D3vlTAfBgNVHSMEGDAWgBSiY4BoP6E4Rx6tSi0i
30+
XDHU5D3vlTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCG9ARQ
31+
S1tOW0PVuJ5H4WU0hRmDn5oUkEu9DzD1WoGGTN6CCM0AfLBo0ARwqntvSNtERIA6
32+
BfVSaeqO6WNrvGDLwi+YcUlTxyGLsGlDz/xeQ7WIVGlbhyTJYH5B1yliRyZN4M2E
33+
hIqWqBMSvtqCnMMJEr/0BsigDIEiEUXwsc6tC77HudXxV0AVs4MLBz3iowkeZMB6
34+
qZAVRKCmVptIsPyP+eO3vIIWi0y7eQx/8WOpW52CYj9MhhDa9/IcJLIRQIOe7fRn
35+
1tL/h+aRMq7ywOrwbO/s2HQ7kG/jFIRj0QMxeCExTzPhND22EVvVisfocXS91QuL
36+
PjZuIWmKwDo/Vvau
37+
-----END CERTIFICATE-----

0 commit comments

Comments
 (0)