@@ -18,8 +18,16 @@ package eventingtlstesting
1818
1919import (
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
8997func 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