@@ -92,7 +92,7 @@ func GenerateCertificateAuthority(commonName string, parentCert *x509.Certificat
9292		},
9393		NotBefore :             now ,
9494		NotAfter :              now .Add (validityPeriod ),
95- 		KeyUsage :              x509 .KeyUsageDigitalSignature  |  x509 .KeyUsageKeyEncipherment  |  x509 .KeyUsageCertSign ,
95+ 		KeyUsage :              x509 .KeyUsageDigitalSignature  |  x509 .KeyUsageKeyEncipherment  |  x509 .KeyUsageCertSign   |   x509 . KeyUsageCRLSign ,
9696		IsCA :                  true ,
9797		ExtKeyUsage :           []x509.ExtKeyUsage {x509 .ExtKeyUsageAny },
9898		BasicConstraintsValid : true ,
@@ -186,6 +186,51 @@ func writeCertificateAndKey(path string, cert *x509.Certificate, key *rsa.Privat
186186	return  nil 
187187}
188188
189+ func  GenerateCRL (cert  * x509.Certificate , privateKey  * rsa.PrivateKey , revokedCerts  []pkix.RevokedCertificate , isExpired  bool ) ([]byte , error ) {
190+ 	now  :=  time .Now ()
191+ 
192+ 	next  :=  now .AddDate (30 , 0 , 0 )
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+ 
189234func  main () {
190235	log .Println ("Generating root CA" )
191236	rootCert , rootKey , err  :=  GenerateCertificateAuthority ("Prometheus Root CA" , nil , nil )
@@ -199,6 +244,12 @@ func main() {
199244		log .Fatal (err )
200245	}
201246
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+ 
202253	log .Println ("Generating server certificate" )
203254	cert , key , err  :=  GenerateCertificate (caCert , caKey , true , "localhost" , net .IPv4 (127 , 0 , 0 , 1 ), net .IPv4 (127 , 0 , 0 , 0 ))
204255	if  err  !=  nil  {
@@ -209,6 +260,16 @@ func main() {
209260		log .Fatal (err )
210261	}
211262
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+ 
212273	log .Println ("Generating client certificate" )
213274	cert , key , err  =  GenerateCertificate (caCert , caKey , false , "localhost" )
214275	if  err  !=  nil  {
@@ -235,11 +296,108 @@ func main() {
235296		log .Fatal (err )
236297	}
237298
299+ 	if  err  :=  os .WriteFile ("testdata/tls-ca-no-root.pem" , b .Bytes (), 0644 ); err  !=  nil  {
300+ 		log .Fatal (err )
301+ 	}
302+ 
238303	if  err  :=  EncodeCertificate (& b , rootCert ); err  !=  nil  {
239304		log .Fatal (err )
240305	}
241306
242307	if  err  :=  os .WriteFile ("testdata/tls-ca-chain.pem" , b .Bytes (), 0644 ); err  !=  nil  {
243308		log .Fatal (err )
244309	}
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+ 
245403}
0 commit comments