@@ -92,7 +92,7 @@ func GenerateCertificateAuthority(commonName string, parentCert *x509.Certificat
92
92
},
93
93
NotBefore : now ,
94
94
NotAfter : now .Add (validityPeriod ),
95
- KeyUsage : x509 .KeyUsageDigitalSignature | x509 .KeyUsageKeyEncipherment | x509 .KeyUsageCertSign ,
95
+ KeyUsage : x509 .KeyUsageDigitalSignature | x509 .KeyUsageKeyEncipherment | x509 .KeyUsageCertSign | x509 . KeyUsageCRLSign ,
96
96
IsCA : true ,
97
97
ExtKeyUsage : []x509.ExtKeyUsage {x509 .ExtKeyUsageAny },
98
98
BasicConstraintsValid : true ,
@@ -186,6 +186,51 @@ func writeCertificateAndKey(path string, cert *x509.Certificate, key *rsa.Privat
186
186
return nil
187
187
}
188
188
189
+ func GenerateCRL (cert * x509.Certificate , privateKey * rsa.PrivateKey , revokedCerts []pkix.RevokedCertificate , isExpired bool ) ([]byte , error ) {
190
+ now := time .Now ()
191
+
192
+ next := now .Add (30 * 24 * time .Hour )
193
+ if isExpired {
194
+ next = now
195
+ }
196
+
197
+ crl := & x509.RevocationList {
198
+ SignatureAlgorithm : x509 .SHA256WithRSA ,
199
+ ThisUpdate : now ,
200
+ NextUpdate : next ,
201
+ RevokedCertificates : revokedCerts ,
202
+ Number : big .NewInt (1 ),
203
+ Issuer : cert .Subject ,
204
+ }
205
+
206
+ crlBytes , err := x509 .CreateRevocationList (rand .Reader , crl , cert , privateKey )
207
+ if err != nil {
208
+ return nil , fmt .Errorf ("cannot create revocation list: %v" , err )
209
+ }
210
+
211
+ return crlBytes , nil
212
+ }
213
+
214
+ func writeCRLs (filename string , crlData [][]byte ) error {
215
+ crlPemBytes := new (bytes.Buffer )
216
+ for _ , data := range crlData {
217
+ crlPem := & pem.Block {
218
+ Type : "X509 CRL" ,
219
+ Bytes : data ,
220
+ }
221
+ err := pem .Encode (crlPemBytes , crlPem )
222
+ if err != nil {
223
+ return err
224
+ }
225
+ }
226
+
227
+ if crlPemBytes == nil {
228
+ return fmt .Errorf ("empty CRL to write" )
229
+ }
230
+
231
+ return os .WriteFile (filename , crlPemBytes .Bytes (), 0644 )
232
+ }
233
+
189
234
func main () {
190
235
log .Println ("Generating root CA" )
191
236
rootCert , rootKey , err := GenerateCertificateAuthority ("Prometheus Root CA" , nil , nil )
@@ -199,6 +244,12 @@ func main() {
199
244
log .Fatal (err )
200
245
}
201
246
247
+ log .Println ("Generating Irrelevant CA" )
248
+ irlvtCert , irlvtKey , err := GenerateCertificateAuthority ("Prometheus TLS Irrelevant CA" , nil , nil )
249
+ if err != nil {
250
+ log .Fatal (err )
251
+ }
252
+
202
253
log .Println ("Generating server certificate" )
203
254
cert , key , err := GenerateCertificate (caCert , caKey , true , "localhost" , net .IPv4 (127 , 0 , 0 , 1 ), net .IPv4 (127 , 0 , 0 , 0 ))
204
255
if err != nil {
@@ -209,6 +260,16 @@ func main() {
209
260
log .Fatal (err )
210
261
}
211
262
263
+ log .Println ("Generating revoked server certificate" )
264
+ revokedCert , revokedKey , err := GenerateCertificate (caCert , caKey , true , "localhost" , net .IPv4 (127 , 0 , 0 , 1 ), net .IPv4 (127 , 0 , 0 , 0 ))
265
+ if err != nil {
266
+ log .Fatal (err )
267
+ }
268
+
269
+ if err := writeCertificateAndKey ("testdata/server_revoked" , revokedCert , revokedKey ); err != nil {
270
+ log .Fatal (err )
271
+ }
272
+
212
273
log .Println ("Generating client certificate" )
213
274
cert , key , err = GenerateCertificate (caCert , caKey , false , "localhost" )
214
275
if err != nil {
@@ -235,11 +296,108 @@ func main() {
235
296
log .Fatal (err )
236
297
}
237
298
299
+ if err := os .WriteFile ("testdata/tls-ca-no-root.pem" , b .Bytes (), 0644 ); err != nil {
300
+ log .Fatal (err )
301
+ }
302
+
238
303
if err := EncodeCertificate (& b , rootCert ); err != nil {
239
304
log .Fatal (err )
240
305
}
241
306
242
307
if err := os .WriteFile ("testdata/tls-ca-chain.pem" , b .Bytes (), 0644 ); err != nil {
243
308
log .Fatal (err )
244
309
}
310
+
311
+ if err := EncodeCertificate (& b , irlvtCert ); err != nil {
312
+ log .Fatal (err )
313
+ }
314
+
315
+ if err := os .WriteFile ("testdata/tls-ca-chain-add-irlvt-ca.pem" , b .Bytes (), 0644 ); err != nil {
316
+ log .Fatal (err )
317
+ }
318
+
319
+ log .Println ("Generating CRLs" )
320
+ crlProp_revokedCert := []pkix.RevokedCertificate {
321
+ {
322
+ SerialNumber : revokedCert .SerialNumber ,
323
+ RevocationTime : time .Now (),
324
+ },
325
+ }
326
+
327
+ crl_RevokedCert , err := GenerateCRL (caCert , caKey , crlProp_revokedCert , false )
328
+ if err != nil {
329
+ log .Fatal (err )
330
+ }
331
+
332
+ if err := writeCRLs ("testdata/crl_cert_revoked.pem" , [][]byte {crl_RevokedCert }); err != nil {
333
+ log .Fatal (err )
334
+ }
335
+
336
+ crl_RevokedCert_expired , err := GenerateCRL (caCert , caKey , crlProp_revokedCert , true )
337
+ if err != nil {
338
+ log .Fatal (err )
339
+ }
340
+
341
+ if err := writeCRLs ("testdata/crl_cert_revoked_expired.pem" , [][]byte {crl_RevokedCert_expired }); err != nil {
342
+ log .Fatal (err )
343
+ }
344
+
345
+ crl_irlvtRevokedCert , err := GenerateCRL (irlvtCert , irlvtKey , crlProp_revokedCert , false )
346
+ if err != nil {
347
+ log .Fatal (err )
348
+ }
349
+
350
+ crlProp_empty := []pkix.RevokedCertificate {
351
+ {
352
+ SerialNumber : big .NewInt (1 ),
353
+ RevocationTime : time .Now (),
354
+ },
355
+ }
356
+
357
+ crl_InterCA_Empty , err := GenerateCRL (caCert , caKey , crlProp_empty , false )
358
+ if err != nil {
359
+ log .Fatal (err )
360
+ }
361
+
362
+ if err := writeCRLs ("testdata/crl_inter_empty.pem" , [][]byte {crl_InterCA_Empty }); err != nil {
363
+ log .Fatal (err )
364
+ }
365
+
366
+ crlProp_RevokedInterCA := []pkix.RevokedCertificate {
367
+ {
368
+ SerialNumber : caCert .SerialNumber ,
369
+ RevocationTime : time .Now (),
370
+ },
371
+ }
372
+
373
+ crl_revokedInterCA , err := GenerateCRL (rootCert , rootKey , crlProp_RevokedInterCA , false )
374
+ if err != nil {
375
+ log .Fatal (err )
376
+ }
377
+
378
+ crl_Root_Empty , err := GenerateCRL (rootCert , rootKey , crlProp_empty , false )
379
+ if err != nil {
380
+ log .Fatal (err )
381
+ }
382
+
383
+ if err := writeCRLs ("testdata/crl_root_empty.pem" , [][]byte {crl_Root_Empty }); err != nil {
384
+ log .Fatal (err )
385
+ }
386
+
387
+ if err := writeCRLs ("testdata/crl_chain_all_empty.pem" , [][]byte {crl_InterCA_Empty , crl_Root_Empty }); err != nil {
388
+ log .Fatal (err )
389
+ }
390
+
391
+ if err := writeCRLs ("testdata/crl_chain_cert_revoked.pem" , [][]byte {crl_Root_Empty , crl_RevokedCert }); err != nil {
392
+ log .Fatal (err )
393
+ }
394
+
395
+ if err := writeCRLs ("testdata/crl_chain_inter_ca_cert_revoked.pem" , [][]byte {crl_revokedInterCA , crl_InterCA_Empty }); err != nil {
396
+ log .Fatal (err )
397
+ }
398
+
399
+ if err := writeCRLs ("testdata/crl_chain_irlvt_cert_revoked.pem" , [][]byte {crl_InterCA_Empty , crl_irlvtRevokedCert }); err != nil {
400
+ log .Fatal (err )
401
+ }
402
+
245
403
}
0 commit comments