@@ -5,6 +5,13 @@ package certsyncpod
5
5
import (
6
6
"bytes"
7
7
"context"
8
+ "crypto/ecdsa"
9
+ "crypto/elliptic"
10
+ "crypto/rand"
11
+ "crypto/x509"
12
+ "crypto/x509/pkix"
13
+ "encoding/pem"
14
+ "math/big"
8
15
"os"
9
16
"path/filepath"
10
17
"sync"
@@ -28,6 +35,10 @@ func TestDynamicCertificates(t *testing.T) {
28
35
Name : "s1" ,
29
36
}
30
37
38
+ // Generate all necessary keypairs.
39
+ tlsCert , tlsKey := generateKeypair (t )
40
+ tlsCertUpdated , tlsKeyUpdated := generateKeypair (t )
41
+
31
42
// Write the keypair into a secret directory.
32
43
secretDir := filepath .Join (t .TempDir (), "secrets" , om .Name )
33
44
certFile := filepath .Join (secretDir , "tls.crt" )
@@ -36,10 +47,10 @@ func TestDynamicCertificates(t *testing.T) {
36
47
if err := os .MkdirAll (secretDir , 0700 ); err != nil {
37
48
t .Fatalf ("Failed to create secret directory %q: %v" , secretDir , err )
38
49
}
39
- if err := os .WriteFile (certFile , [] byte ( tlsCert ) , 0600 ); err != nil {
50
+ if err := os .WriteFile (certFile , tlsCert , 0600 ); err != nil {
40
51
t .Fatalf ("Failed to write TLS certificate into %q: %v" , certFile , err )
41
52
}
42
- if err := os .WriteFile (keyFile , [] byte ( tlsKey ) , 0600 ); err != nil {
53
+ if err := os .WriteFile (keyFile , tlsKey , 0600 ); err != nil {
43
54
t .Fatalf ("Failed to write TLS key into %q: %v" , keyFile , err )
44
55
}
45
56
@@ -52,7 +63,7 @@ func TestDynamicCertificates(t *testing.T) {
52
63
53
64
// Check the initial keypair is loaded.
54
65
cert , key := dc .CurrentCertKeyContent ()
55
- if ! bytes .Equal (cert , [] byte ( tlsCert )) || ! bytes .Equal (key , [] byte ( tlsKey ) ) {
66
+ if ! bytes .Equal (cert , tlsCert ) || ! bytes .Equal (key , tlsKey ) {
56
67
t .Fatal ("Unexpected initial keypair loaded" )
57
68
}
58
69
@@ -68,7 +79,7 @@ func TestDynamicCertificates(t *testing.T) {
68
79
69
80
// Poll until update detected.
70
81
recorder := eventstesting .NewTestingEventRecorder (t )
71
- files := map [string ]string {
82
+ files := map [string ][] byte {
72
83
"tls.crt" : tlsCertUpdated ,
73
84
"tls.key" : tlsKeyUpdated ,
74
85
}
@@ -82,110 +93,63 @@ func TestDynamicCertificates(t *testing.T) {
82
93
// Check the loaded content matches.
83
94
// This is most probably updated based on write in a previous Poll invocation.
84
95
cert , key := dc .CurrentCertKeyContent ()
85
- return bytes .Equal (cert , [] byte ( tlsCertUpdated )) && bytes .Equal (key , [] byte ( tlsKeyUpdated ) ), nil
96
+ return bytes .Equal (cert , tlsCertUpdated ) && bytes .Equal (key , tlsKeyUpdated ), nil
86
97
})
87
98
if err != nil {
88
99
t .Fatalf ("Failed to wait for dynamic certificate: %v" , err )
89
100
}
90
101
}
91
102
92
- const (
93
- tlsCert = `-----BEGIN CERTIFICATE-----
94
- MIIDDzCCAfegAwIBAgIUNizZp8wiNCSTBiwtNLz2uS/UxJYwDQYJKoZIhvcNAQEL
95
- BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI1MDkxODEyMDI1NFoXDTI1MTAx
96
- ODEyMDI1NFowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF
97
- AAOCAQ8AMIIBCgKCAQEAwCFBu6vi5JqeCEHJvE97xdhlXX2BEgWS16ikEa6oGOBi
98
- Q0P1TdW+0GgQYRviuWq0/3Ql2GnrWlulVMZfVGDnwVJNjRvNbPUCOXieP8JIj79x
99
- Hua6tdwvin69kB6yvhMKPi6h5tmPDgxmcOAU/IZzSkm62kJ8ygJ7nlpD3VcBowj1
100
- 2nGQf3KVXG50YU+/2IFP8iaEj/KsCs1yd0oXlqHHELIWq+9scHYdA1pH+CqZC+u0
101
- CKJKG2Umgj4cgby9ltOqOsmr2rMXVq5tle381tu9QGqEeJJ3TpnmCb9z5+TLdUAB
102
- jdBHQKiKXhhVpIKbDScsZ1rmVZ34t1jFFJlHFflqCQIDAQABo1kwVzAUBgNVHREE
103
- DTALgglsb2NhbGhvc3QwCwYDVR0PBAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMB
104
- MB0GA1UdDgQWBBSzdSuyIKFJtdCOA3nPtV/WJMhuNDANBgkqhkiG9w0BAQsFAAOC
105
- AQEAWhg6qUZ5l6qHx6OdhlekkVtmgAIplxtpMHbmCjMFcTA+qc1W56a6X/9fPRyy
106
- Wb/8B2biu2cQ9uoLiiZo+2VhnsmvbqeSWhAVPkTWf1ojDq3VmfK+y12rwX5t4VOv
107
- NdOJabSufjjmTGzjuNqD+6n43JRu42TCAgbMccdGQzHk9xIBRD7Ik886PYYe3E+G
108
- 4Wha7/jMFaUF0z0FBqIKJbDPB51R2w8g5D5mR4Ylm9tRidxz39qfNHNEWPpp/pVH
109
- l5h1v53gThzzktCzKQKjgUTzUi4qvqnxRPxHgixfAbvvSYlC3+HizVSuK6j53t+k
110
- qdEbfjD2fIjpTY91oFX78tVdoA==
111
- -----END CERTIFICATE-----
112
- `
113
- tlsKey = `-----BEGIN PRIVATE KEY-----
114
- MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDAIUG7q+Lkmp4I
115
- Qcm8T3vF2GVdfYESBZLXqKQRrqgY4GJDQ/VN1b7QaBBhG+K5arT/dCXYaetaW6VU
116
- xl9UYOfBUk2NG81s9QI5eJ4/wkiPv3Ee5rq13C+Kfr2QHrK+Ewo+LqHm2Y8ODGZw
117
- 4BT8hnNKSbraQnzKAnueWkPdVwGjCPXacZB/cpVcbnRhT7/YgU/yJoSP8qwKzXJ3
118
- SheWoccQshar72xwdh0DWkf4KpkL67QIokobZSaCPhyBvL2W06o6yavasxdWrm2V
119
- 7fzW271AaoR4kndOmeYJv3Pn5Mt1QAGN0EdAqIpeGFWkgpsNJyxnWuZVnfi3WMUU
120
- mUcV+WoJAgMBAAECggEAEMuXdHFtLzC4+d3OZdDI8B2fltGe09V65bFPTmBnP212
121
- CY1KR1iVCqDeNa77XdwPIHmlyUpREaALTuLceILUH5kzQE+a4Jh2blG1+7rfHvnM
122
- SLhAwB8UZNX5ejzEwUrmzVLEQmroT4ET/3AHRZ/3OhpB5EyFnh8jcU9QuWuesAK0
123
- biAfn67Vxc3AOUuzvQMqltgJSzc6MBUETyBmxUEXsGxpSw3Ma/ieMPs8hTS60aU3
124
- TrzkgHD9mBTdpLpSYHmAXYJJOTylVcYYuTWzEoEjNJDTaZf/HiQTC93NZ/M2Kl6s
125
- kSwT+HaRDfU0BaBbjfPNSXwEUhSvd0JuEie7cpdAxQKBgQD7ivVizx9QUbQkJfkb
126
- OokCXo/Tjz5uqGq7gMvDdnl34PMju/tG/e+DHphEpetd5cDPg5nEpwhDe7ztbepn
127
- 8UrDTV5RPkwNs9u9eskW8cmELsKjpoodMCXOeEaT3QeYA2fwe5A1X3ILSAPPZAOK
128
- 0YKzr3S/7JSMCiD8+OlxrkPVywKBgQDDiMqFugvMUcDhgByj9aVitkfn3VXB/tGE
129
- D3DLLoHnt8MpehIbzkMeoDEqqz+K8ItHuOdPSA7dhqP2CG2zDBeWlVxlfZ7S1WMW
130
- YEwp2frdnLbCXwo93zc5Cje2XMnkU44GzPW1LdLTbY/PodkNAHa0F4LeayMBKsmH
131
- d7Oxu2rk+wKBgFWhOmPGqpxHFBHyM1kHljiORFv6uYAmKR9nevYxUKx0kZCqn6HN
132
- NEnokmFcMkGmwvphjGkbi36dkvUoo9F6nL7bia4SjQVlIvrf37DF4pny6SOYwA+r
133
- olMlMrGHXtxq3GlLRw5ETah1fYaOP350UBAnPJFRUkhR8mTrv1yJvGH9AoGAUPTL
134
- 1P4ocFnQ4Axoz0GfTfVmZAtxvDZCjMjPzG/e/Q9KUFvoL3cAtydf8+ifEGlzYSif
135
- LGYLMZDTRcRLlvwEsCX68VJHdcc/lT4dip5jjWmbCXLMDL3kYUtnsatNM6mcfhhS
136
- CseEKGGOT0sVUJrGit3JI0l8XrlWYy4eShHsug0CgYBDTFYrnc8pSZn5SQwHVRkc
137
- hEW+WWdaTjmuaUx0I/ce4rocLHiO+bTM2hjYNL52xn62L2N7p+1wQBfChcI1wFbU
138
- w6An158oz0ldvlmxQk7CIyEoQNY+snSxOmZFXILDdp7mPbHhtavJj5vruY5VIHYs
139
- n4dXmvaEIZfo5M7UBlYW1A==
140
- -----END PRIVATE KEY-----
141
- `
142
- tlsCertUpdated = `-----BEGIN CERTIFICATE-----
143
- MIIDDzCCAfegAwIBAgIUIcqFTfK2NxKU2YAyPdt/IL2TGl0wDQYJKoZIhvcNAQEL
144
- BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI1MDkxODEyNDI1NloXDTI1MTAx
145
- ODEyNDI1NlowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF
146
- AAOCAQ8AMIIBCgKCAQEAlwJe+8tKBE/Q+epUKl7UI+R/8es0U11BuaQIF6iT0FvE
147
- DbEyFLAxvNPoE9m+Bu/wXivzkfEcXaxpHcDE6jA/A51TX/cDKwZAD6aMOovmG4b+
148
- SJDTtbtRzZcEwyWqwK43cbK12O/D+TTV2/0lZYisA/EoAoWjGb6uY053xcBn6+Cf
149
- +6+cZ5slBizrIcY87U2a039hRBaAb/1Wss+Ogj22eYJotYxFeuptWhqKP4cvn6nZ
150
- r+HPaio/Eq2LRVb0tAzSuIATleo9k9443EnNB63TkgeW2RTTsFvSK6R7EWN4Kcdk
151
- ubxhPMuUyWgCsSEwYTu19BVrwBIlZjZpNETsqtbDbQIDAQABo1kwVzAUBgNVHREE
152
- DTALgglsb2NhbGhvc3QwCwYDVR0PBAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMB
153
- MB0GA1UdDgQWBBSkjhnvdVmMb+9DKQ4lQNmnwM1IHjANBgkqhkiG9w0BAQsFAAOC
154
- AQEAU0YlNhE0iaNJk/rvlXqkD/1O4b7pM8+aOHN54crVAgaA3fNZOcNelMuxPhFj
155
- mHpvM8L09wwlueVHudFier5g41mhgbkN7jsHZJlKG7ZjW5GJVggshn+bFmAYK/VS
156
- JSvJe+QcUMJeWANjbV3pMgg3Is/edhOMeJawvqHjSQMNT6qln4/9MgBTuSiEnpOh
157
- 3MzmMXaFQLfFIDeuQY0dTM6Sx2Yn8EAmMuhjClLUdlPMskOk4vasqnbZuARp6bUe
158
- ZofmJ2YNG4PsXZQak7p6WSkt9HqGll7a9UBFSAI2O4a3D3MahdRNMcwi8LDzZr/y
159
- Vj72VewkK8yf+sPJ/nmkY/2j/w==
160
- -----END CERTIFICATE-----
161
- `
162
- tlsKeyUpdated = `-----BEGIN PRIVATE KEY-----
163
- MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCXAl77y0oET9D5
164
- 6lQqXtQj5H/x6zRTXUG5pAgXqJPQW8QNsTIUsDG80+gT2b4G7/BeK/OR8RxdrGkd
165
- wMTqMD8DnVNf9wMrBkAPpow6i+Ybhv5IkNO1u1HNlwTDJarArjdxsrXY78P5NNXb
166
- /SVliKwD8SgChaMZvq5jTnfFwGfr4J/7r5xnmyUGLOshxjztTZrTf2FEFoBv/Vay
167
- z46CPbZ5gmi1jEV66m1aGoo/hy+fqdmv4c9qKj8SrYtFVvS0DNK4gBOV6j2T3jjc
168
- Sc0HrdOSB5bZFNOwW9IrpHsRY3gpx2S5vGE8y5TJaAKxITBhO7X0FWvAEiVmNmk0
169
- ROyq1sNtAgMBAAECggEADbGaWW0C5kcypScZwMnepO6Yp6Bzm0euqR312edgmBlq
170
- Ou+hofykVgJFXl91ev2RJ4kGymo570iuM5OCh9YeML64i9BDikhD0OeCeeCr2j0w
171
- m/X+LNGyxlj2hpfI1zY1MutI0EZV2ChxaESZeo6dQrJAtZHWy4PeHoVEGTuscNhH
172
- FZSUjqnJxxYUIH5ypHF13yYE++BtTfUW0lKVoYjV1w8a/qKiJTLukZy452wFkJ6a
173
- pwOmZF0F5oxrhe8hdG6WP3CeGnr4Bv6OKSmBG3N/fNbEXfk7zMLiZo74hUYgrKfy
174
- YfwHI5pbwURl+Ust69uyn8EDRfBhqQCNqdB4iNOA4QKBgQDOnx3MrluSDSb+kJ86
175
- CwwN6MCWLn20Rq36afmTW8iUvSmbKO/KyYbrVY/+qsoSQ89L3doE5O2YHsu08OJ7
176
- BGJMxfFZ71+OTcvCl5iirkg/2g530cf1/QcYhtqc6+WDvluZUxt4ZpE+jyERQaG3
177
- EzaJLPoIbMT+DyCwfXcKWjndCQKBgQC7GPRzA4oTj0csxLuH8y4yIT2wbMPHiSML
178
- f96OHroUhBeVbruL4y5cu9EJyYKIM9Q1yi13Ce+T+YLlFvUgUpPK/zpF5sPICz+Z
179
- TRs055t3tG4QOLm6gfrGlyka6n5CLlANT1mSDghlfh1zXZ1m/vME6cFxwgVzGBlE
180
- ptxBoQiwRQKBgEB+GecRZTOpN0quCYUsfY6536MAz+u9RACto2EDfRAwGxR7Kp25
181
- WYuLIW70EC6zS7j6flqYujCJLDxGE+sh6yzbfAH+XW0lizwp5VKh45tKjMmJiUiW
182
- uehF72abmwAMIrsw3ZovKZbFRiUEv11NefBHQaPvj21de26bOtTYZMdBAoGAMMt9
183
- VVGi/R7s7RwR3I7riV9p+00icjOt1B3xKReSaC9bBznt57nEKaNCDU9kn6kEu1KT
184
- MOyCcxErthuaqmde7B5MUFay0MU+PPkDE3Uj8sA3xDtHFQE5KfnaWo61hwUVE6OS
185
- NKk8P1v4ylGr72SmdK2SKdz0FuQ+Es2BvAwHfBECgYAPVRckudv8Yx4/dXVkhBkM
186
- b5V7VUwWYq2Dmwzf83p2C3gqoXbO8d91pkIQhcc+LhC4umYisNFx5cuEfkzJXTBT
187
- zQWIuZVz5eekCOb+Egi/kBrheenpc+/7NXCx2km1zegN4dn2Njusb0XgLVFMvCkQ
188
- a3PRfBcOqez6+lxuQkb+NQ==
189
- -----END PRIVATE KEY-----
190
- `
191
- )
103
+ // generateKeypair returns (cert, key).
104
+ func generateKeypair (t * testing.T ) ([]byte , []byte ) {
105
+ t .Helper ()
106
+
107
+ privateKey , err := ecdsa .GenerateKey (elliptic .P224 (), rand .Reader )
108
+ if err != nil {
109
+ t .Fatalf ("Failed to generate TLS key: %v" , err )
110
+ }
111
+
112
+ notBefore := time .Now ()
113
+ notAfter := notBefore .Add (1 * time .Hour )
114
+
115
+ serialNumberLimit := new (big.Int ).Lsh (big .NewInt (1 ), 128 )
116
+ serialNumber , err := rand .Int (rand .Reader , serialNumberLimit )
117
+ if err != nil {
118
+ t .Fatalf ("Failed to generate serial number for TLS keypair: %v" , err )
119
+ }
120
+
121
+ template := x509.Certificate {
122
+ SerialNumber : serialNumber ,
123
+ Subject : pkix.Name {
124
+ Organization : []string {"Example Org" },
125
+ },
126
+ NotBefore : notBefore ,
127
+ NotAfter : notAfter ,
128
+ KeyUsage : x509 .KeyUsageDigitalSignature ,
129
+ ExtKeyUsage : []x509.ExtKeyUsage {x509 .ExtKeyUsageServerAuth },
130
+ BasicConstraintsValid : true ,
131
+ DNSNames : []string {"example.com" },
132
+ }
133
+
134
+ publicKeyBytes , err := x509 .CreateCertificate (rand .Reader , & template , & template , & privateKey .PublicKey , privateKey )
135
+ if err != nil {
136
+ t .Fatalf ("Failed to create TLS certificate: %v" , err )
137
+ }
138
+
139
+ var certOut bytes.Buffer
140
+ if err := pem .Encode (& certOut , & pem.Block {Type : "CERTIFICATE" , Bytes : publicKeyBytes }); err != nil {
141
+ t .Fatalf ("Failed to write certificate PEM: %v" , err )
142
+ }
143
+
144
+ privateKeyBytes , err := x509 .MarshalPKCS8PrivateKey (privateKey )
145
+ if err != nil {
146
+ t .Fatalf ("Unable to marshal private key: %v" , err )
147
+ }
148
+
149
+ var keyOut bytes.Buffer
150
+ if err := pem .Encode (& keyOut , & pem.Block {Type : "PRIVATE KEY" , Bytes : privateKeyBytes }); err != nil {
151
+ t .Fatalf ("Failed to write certificate PEM: %v" , err )
152
+ }
153
+
154
+ return certOut .Bytes (), keyOut .Bytes ()
155
+ }
0 commit comments