Skip to content

Commit f2bc8e5

Browse files
[release-1.21] Generate test certs dynamically [skip-dot-release] (knative#9012) (#1849)
Generate test certs dynamically instead of hardcoding them Co-authored-by: Knative Prow Robot <automation+prow-robot@knative.team>
1 parent b77d08f commit f2bc8e5

File tree

1 file changed

+134
-90
lines changed

1 file changed

+134
-90
lines changed

pkg/eventingtls/eventingtlstesting/eventingtlstesting.go

Lines changed: 134 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,16 @@ package eventingtlstesting
1818

1919
import (
2020
"context"
21+
"crypto/rand"
22+
"crypto/rsa"
23+
"crypto/x509"
24+
"crypto/x509/pkix"
25+
"encoding/pem"
26+
"math/big"
27+
"net"
2128
"net/http"
2229
"testing"
30+
"time"
2331

2432
"github.com/stretchr/testify/assert"
2533
corev1 "k8s.io/api/core/v1"
@@ -87,94 +95,130 @@ func StartServer(ctx context.Context, t *testing.T, port int, handler http.Handl
8795
}
8896

8997
func loadCerts() ([]byte, []byte, []byte) {
90-
/*
91-
Provisioned using:
92-
openssl req -x509 -nodes -new -sha256 -days 1024 -newkey rsa:2048 -keyout RootCA.key -out RootCA.pem -subj "/C=US/CN=Knative-Example-Root-CA"
93-
openssl x509 -outform pem -in RootCA.pem -out RootCA.crt
94-
openssl req -new -nodes -newkey rsa:2048 -keyout localhost.key -out localhost.csr -subj "/C=US/ST=YourState/L=YourCity/O=Example-Certificates/CN=localhost.local"
95-
openssl x509 -req -sha256 -days 1024 -in localhost.csr -CA RootCA.pem -CAkey RootCA.key -CAcreateserial -extfile domains.ext -out localhost.crt
96-
Copy:
97-
- RootCA.crt for ca
98-
- localhost.key for key
99-
- localhost.crt for crt
100-
domains.ext file:
101-
authorityKeyIdentifier=keyid,issuer
102-
basicConstraints=CA:FALSE
103-
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
104-
subjectAltName = @alt_names
105-
[alt_names]
106-
DNS.1 = localhost
107-
IP.1 = 127.0.0.1
108-
*/
109-
return []byte(`
110-
-----BEGIN CERTIFICATE-----
111-
MIIDPzCCAiegAwIBAgIUOF3U5UMwffSmdo24IVU1k+qix3YwDQYJKoZIhvcNAQEL
112-
BQAwLzELMAkGA1UEBhMCVVMxIDAeBgNVBAMMF0tuYXRpdmUtRXhhbXBsZS1Sb290
113-
LUNBMB4XDTIzMDYwNjE0MDY1NFoXDTI2MDMyNjE0MDY1NFowLzELMAkGA1UEBhMC
114-
VVMxIDAeBgNVBAMMF0tuYXRpdmUtRXhhbXBsZS1Sb290LUNBMIIBIjANBgkqhkiG
115-
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsJEA/+FW8e/ChmpseeH+UMtpP3PIq4VO26yh
116-
fg3RSWKRbEnpkusWX6tM5NIZ9HqZOhB9dvb0OAC+YBM5ce8eA1/5tIUcxOzvMo5S
117-
Oe+5cOgzZPLNesPBD+vteFXeD/9Hg75KfxctgyYfKqAE4Q8afaxs29/9K4wZkdE7
118-
Fs4ED8r6hxf+7wgVSurnHiQnupHOb3BCQEGFm4w5/YJMhJFM29+LtIa5iZvQdlIC
119-
zrIiLSckaRCiuJH2U5HCxk6WpodyoD5ffqzX7/+xismUwsX9opnMfdz7vT4ZYvKc
120-
5O0u6/mx9fvhCL7hVwz8/FKvd1+Z4WnGoL/Iz3g+T/qdMbA+1wIDAQABo1MwUTAd
121-
BgNVHQ4EFgQU51Q84l/eECxUhLRPhlcoLougg0owHwYDVR0jBBgwFoAU51Q84l/e
122-
ECxUhLRPhlcoLougg0owDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC
123-
AQEAZVXtix62c6VVAEZHsSTPwlMwGjZ67UCd6NxeY5IgXdT/vmorlrsoZa0FYYkU
124-
TdWOHt7Q1C48W+tA2yMTPGs240Zradam2CXAxEvL7/aC6GEFs7vhkq6riwJ/erR3
125-
ZAZjcWi5Qk03q7eS61JJvaV9+fKg+F2BB2EqaCPo7HMMSXO81aeHEMl/AQsNPnur
126-
2VG1tchMQvfakRf53H1hWu5h4APuZo1MTkPmBOTLZG7eAJTtfVWz1aPwB1rUMCyP
127-
wSdZWoEx7ye2kUHEyRKdRGbHyJtY9YYvaROznzxqVpIqHxnRQnE/If7kcN4t/7vi
128-
28zWIDKzJ8je40SPcLSfplRvBQ==
129-
-----END CERTIFICATE-----`), []byte(`
130-
-----BEGIN PRIVATE KEY-----
131-
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCodsq2l7lP1LMw
132-
hh9j4FQvULIfvcwiz3WyBkeLvQPk044ZRX50bwm2llTKwEvWyqnmctjcS5RiKItw
133-
9kg6eXA3Z9CBuPyJkrvH/4OO2wOBgyBD8k3LqNtaqN0Qq2Y3JbQ/PBf5btNMmYFB
134-
gostqCBsiDIF1KqkpCHpvLBLPte9bLv4ZAxNecC6p/fXUbXTWJ4SFNhdZrw62Rs4
135-
boq8qTs0PceDJiLdvqwngGNneCdehFXR3citMCA8SxyD8E2qIIOLuOEf54s9zR7C
136-
d+D0h+XQmHICAcz3Yo4a27dNFUc2LHcp9a2+ASHTnKsR6Xhndo/IcT7/qbYq7/kJ
137-
lfN66ObzAgMBAAECggEADBYpyRvtobqi+JJG4kWQBK0HepuFb+Hukc09iNsQ0nQT
138-
N+Dyh6wHyF/UyY8uYcS8l9oZkQSjKr+58WraF8fqsy7xmL0K8VvjuR+t8qvn/nzH
139-
7dgOmNQOmNyQr8d8V+yOmBLZrX20D0TcLzUMg0QSv3auEBkH/TQBcuGkzGE/3Uk4
140-
DT/L//DREjVw+DAaFd53UWWhSnLOkQAsY+zR+HktQH0CEtwMjbkBWMgCkgX7/v9w
141-
gBQLwR7uw5w0Kn8ArgqXj5b5naqHhNzMPj65kMHFjYejSDsjPntToz5YrDRsd4L3
142-
EYAcKcG4fYjJ8vYbRjG7SYCxX7HsvJUhqZT4ds/DsQKBgQDTrSN8m60ZPwmvAG+6
143-
Tpy3Hpf+klO/AE/FQ6WQ8K77McBoRA4awFcjqasqxkTHCl8FXXdWoEe+OIJ+MXzu
144-
5zX5J1dAOl++sgdOvQFW4y4H+FOHD5q5SHFzdI8d65HJy6SI6BVJz4lR51bSU5CQ
145-
qkdh0Sbh1hAACIsmZTApaXY03wKBgQDLvUShkRaJC/pzN7yCb0Cu4VxBV90IkE0n
146-
INHNML8/KCbGJ5EmLk5uJt1sWb0e8PpUgoavnljfUUKyNfd/ltr9slE6uRhy9net
147-
qg1A0CmArFJgOncA3bu92CvvzzcDPsnHCBnLKpTfUSThk8Sxftg0bqKEV3sy5Py1
148-
9x6Sp7QcbQKBgQCKRjDHRn6F3mr5+aQCpTW0XXTWpEm2nIJ/jxgJnWAA0VgqBELe
149-
cMS7lCsvLwNgrkKyI4NAgEU9WnbL7pH5EeptDqjtWPSQgoVJhyfn1VGNfUc7FBNz
150-
c4JA9GRFHExI8RFTKaA2bi765M8PZ+0ow0ML/++RWR9slign9bPHaZABKwKBgHz9
151-
unMcXaTqMlYpJX8n3ZjsLPrxemrcjFiq68tkUo/ehBsg/w1bb0ZolYL5curej9T0
152-
1sg67u7iHXbTYOlnlSX7FZZfI76zsixanRLcIfoMveTHOWbQoXMQgbP3fhqBlKyE
153-
Lb7UesyeLXAuhYcW+HECRrXGLZDFprvDxX/XXsnpAoGBAJdaCxiy7ZXDrJHJDzGp
154-
Ntxv2SbGghJwlmWYh7BP/+Cb6vUWG4MTzUBIzKfk4Z32xjFwDxKi3SW+34uZ6/fD
155-
Ptt315Oq0odZvrdGtJoGud/p9nCHUiLGHwRH9NrDtTcO9zR55oYc0pJk0EfrXpsb
156-
r5IiDpxJPL1q0JmKeA+Fr4wy
157-
-----END PRIVATE KEY-----`), []byte(`
158-
-----BEGIN CERTIFICATE-----
159-
MIIDoDCCAoigAwIBAgIUSVuHbk6clsj/7Fe3Uc8mFwXU6kMwDQYJKoZIhvcNAQEL
160-
BQAwLzELMAkGA1UEBhMCVVMxIDAeBgNVBAMMF0tuYXRpdmUtRXhhbXBsZS1Sb290
161-
LUNBMB4XDTIzMDYwNjE0MTEwNFoXDTI2MDMyNjE0MTEwNFowbTELMAkGA1UEBhMC
162-
VVMxEjAQBgNVBAgMCVlvdXJTdGF0ZTERMA8GA1UEBwwIWW91ckNpdHkxHTAbBgNV
163-
BAoMFEV4YW1wbGUtQ2VydGlmaWNhdGVzMRgwFgYDVQQDDA9sb2NhbGhvc3QubG9j
164-
YWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCodsq2l7lP1LMwhh9j
165-
4FQvULIfvcwiz3WyBkeLvQPk044ZRX50bwm2llTKwEvWyqnmctjcS5RiKItw9kg6
166-
eXA3Z9CBuPyJkrvH/4OO2wOBgyBD8k3LqNtaqN0Qq2Y3JbQ/PBf5btNMmYFBgost
167-
qCBsiDIF1KqkpCHpvLBLPte9bLv4ZAxNecC6p/fXUbXTWJ4SFNhdZrw62Rs4boq8
168-
qTs0PceDJiLdvqwngGNneCdehFXR3citMCA8SxyD8E2qIIOLuOEf54s9zR7Cd+D0
169-
h+XQmHICAcz3Yo4a27dNFUc2LHcp9a2+ASHTnKsR6Xhndo/IcT7/qbYq7/kJlfN6
170-
6ObzAgMBAAGjdjB0MB8GA1UdIwQYMBaAFOdUPOJf3hAsVIS0T4ZXKC6LoINKMAkG
171-
A1UdEwQCMAAwCwYDVR0PBAQDAgTwMBoGA1UdEQQTMBGCCWxvY2FsaG9zdIcEfwAA
172-
ATAdBgNVHQ4EFgQUtxq3RVNeuFDQEu/I1Hn4u+aCKogwDQYJKoZIhvcNAQELBQAD
173-
ggEBAIP9672LFvNaBWCvZybv62eUoALJzxGFtXTNa9YjkYHZLwJXBa/8cnCLfSiP
174-
6uxUK3lDL4jF8I0VEWe2q3H2R8AllofFQbqeskD5qrrVjMdV/0tuUHI8RPCr9SPP
175-
Y6wIq3dlk98ZlQEwhBz3M4SYpLKyKAn/E/2ScsW+9vcvAAAK32BO27Tk9Ca6ShtQ
176-
p32q5PZOx9+eicXzW7qb4a26k1aFnnaDEUuSQsKXhzVVyt9Xmg14m8ETeEL5xPfI
177-
PiUZitNmqpg2123YyPwE4NW8okkLO03UD3I0I/Bn0mS0sb8xMt/ncR4iWeJOvZSG
178-
0YhYDYdUoSliRZYy5zTe7orFj7Q=
179-
-----END CERTIFICATE-----`)
98+
caCert, _ /* ca1Key */, srvCert, srvKey := mustChain("Knative-Example-Root-CA")
99+
100+
return caCert, srvKey, srvCert
101+
}
102+
103+
func mustChain(cn string) ([]byte, []byte, []byte, []byte) {
104+
caCert, caKey := mustCA(cn)
105+
srvKey, csr := mustCSR()
106+
srvCert := mustSign(csr, caCert, caKey)
107+
108+
return pemCert(caCert.Raw),
109+
pemKey(caKey),
110+
pemCert(srvCert),
111+
pemKey(srvKey)
112+
}
113+
114+
// --- CA (openssl req -x509) ---
115+
func mustCA(cn string) (*x509.Certificate, *rsa.PrivateKey) {
116+
key, err := rsa.GenerateKey(rand.Reader, 2048)
117+
if err != nil {
118+
panic(err)
119+
}
120+
121+
tmpl := &x509.Certificate{
122+
SerialNumber: big.NewInt(time.Now().UnixNano()),
123+
Subject: pkix.Name{
124+
Country: []string{"US"},
125+
CommonName: cn,
126+
},
127+
NotBefore: time.Now(),
128+
NotAfter: time.Now().Add(1024 * 24 * time.Hour),
129+
130+
IsCA: true,
131+
BasicConstraintsValid: true,
132+
KeyUsage: x509.KeyUsageCertSign |
133+
x509.KeyUsageCRLSign |
134+
x509.KeyUsageDigitalSignature,
135+
}
136+
137+
der, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &key.PublicKey, key)
138+
if err != nil {
139+
panic(err)
140+
}
141+
142+
cert, _ := x509.ParseCertificate(der)
143+
return cert, key
144+
}
145+
146+
// --- CSR (openssl req -new) ---
147+
func mustCSR() (*rsa.PrivateKey, []byte) {
148+
key, err := rsa.GenerateKey(rand.Reader, 2048)
149+
if err != nil {
150+
panic(err)
151+
}
152+
153+
csrTmpl := &x509.CertificateRequest{
154+
Subject: pkix.Name{
155+
Country: []string{"US"},
156+
Province: []string{"YourState"},
157+
Locality: []string{"YourCity"},
158+
Organization: []string{"Example-Certificates"},
159+
CommonName: "localhost.local",
160+
},
161+
}
162+
163+
csrDER, err := x509.CreateCertificateRequest(rand.Reader, csrTmpl, key)
164+
if err != nil {
165+
panic(err)
166+
}
167+
168+
return key, csrDER
169+
}
170+
171+
// --- Sign (openssl x509 -req -extfile domains.ext) ---
172+
func mustSign(csrDER []byte, ca *x509.Certificate, caKey *rsa.PrivateKey) []byte {
173+
csr, err := x509.ParseCertificateRequest(csrDER)
174+
if err != nil {
175+
panic(err)
176+
}
177+
178+
tmpl := &x509.Certificate{
179+
SerialNumber: big.NewInt(time.Now().UnixNano()),
180+
Subject: csr.Subject,
181+
182+
NotBefore: time.Now(),
183+
NotAfter: time.Now().Add(1024 * 24 * time.Hour),
184+
185+
// domains.ext equivalent
186+
DNSNames: []string{"localhost"},
187+
IPAddresses: []net.IP{net.ParseIP("127.0.0.1")},
188+
189+
BasicConstraintsValid: true,
190+
IsCA: false,
191+
192+
KeyUsage: x509.KeyUsageDigitalSignature |
193+
x509.KeyUsageContentCommitment | // nonRepudiation
194+
x509.KeyUsageKeyEncipherment |
195+
x509.KeyUsageDataEncipherment,
196+
197+
ExtKeyUsage: []x509.ExtKeyUsage{
198+
x509.ExtKeyUsageServerAuth,
199+
},
200+
}
201+
202+
der, err := x509.CreateCertificate(rand.Reader, tmpl, ca, csr.PublicKey, caKey)
203+
if err != nil {
204+
panic(err)
205+
}
206+
207+
return der
208+
}
209+
210+
// --- PEM helpers ---
211+
func pemCert(der []byte) []byte {
212+
return pem.EncodeToMemory(&pem.Block{
213+
Type: "CERTIFICATE",
214+
Bytes: der,
215+
})
216+
}
217+
218+
func pemKey(key *rsa.PrivateKey) []byte {
219+
b, _ := x509.MarshalPKCS8PrivateKey(key)
220+
return pem.EncodeToMemory(&pem.Block{
221+
Type: "PRIVATE KEY",
222+
Bytes: b,
223+
})
180224
}

0 commit comments

Comments
 (0)