github.com/letsencrypt/boulder@v0.20251208.0/cmd/ceremony/crl.go (about)

     1  package main
     2  
     3  import (
     4  	"crypto"
     5  	"crypto/x509"
     6  	"encoding/pem"
     7  	"errors"
     8  	"fmt"
     9  	"math/big"
    10  	"time"
    11  
    12  	"github.com/letsencrypt/boulder/crl/idp"
    13  	"github.com/letsencrypt/boulder/linter"
    14  )
    15  
    16  func generateCRL(signer crypto.Signer, issuer *x509.Certificate, thisUpdate, nextUpdate time.Time, number int64, revokedCertificates []x509.RevocationListEntry, skipLints []string) ([]byte, error) {
    17  	template := &x509.RevocationList{
    18  		RevokedCertificateEntries: revokedCertificates,
    19  		Number:                    big.NewInt(number),
    20  		ThisUpdate:                thisUpdate,
    21  		NextUpdate:                nextUpdate,
    22  	}
    23  
    24  	if nextUpdate.Before(thisUpdate) {
    25  		return nil, errors.New("thisUpdate must be before nextUpdate")
    26  	}
    27  	if thisUpdate.Before(issuer.NotBefore) {
    28  		return nil, errors.New("thisUpdate is before issuing certificate's notBefore")
    29  	} else if nextUpdate.After(issuer.NotAfter) {
    30  		return nil, errors.New("nextUpdate is after issuing certificate's notAfter")
    31  	}
    32  
    33  	// Verify that the CRL is not valid for more than 12 months as specified in
    34  	// CABF BRs Section 4.9.7
    35  	if nextUpdate.Sub(thisUpdate) > time.Hour*24*365 {
    36  		return nil, errors.New("nextUpdate must be less than 12 months after thisUpdate")
    37  	}
    38  	// Add the Issuing Distribution Point extension.
    39  	idp, err := idp.MakeCACertsExt()
    40  	if err != nil {
    41  		return nil, fmt.Errorf("creating IDP extension: %w", err)
    42  	}
    43  	template.ExtraExtensions = append(template.ExtraExtensions, *idp)
    44  
    45  	err = linter.CheckCRL(template, issuer, signer, skipLints)
    46  	if err != nil {
    47  		return nil, fmt.Errorf("crl failed pre-issuance lint: %w", err)
    48  	}
    49  
    50  	// x509.CreateRevocationList uses an io.Reader here for signing methods that require
    51  	// a source of randomness. Since PKCS#11 based signing generates needed randomness
    52  	// at the HSM we don't need to pass a real reader. Instead of passing a nil reader
    53  	// we use one that always returns errors in case the internal usage of this reader
    54  	// changes.
    55  	crlBytes, err := x509.CreateRevocationList(&failReader{}, template, issuer, signer)
    56  	if err != nil {
    57  		return nil, err
    58  	}
    59  
    60  	return pem.EncodeToMemory(&pem.Block{Type: "X509 CRL", Bytes: crlBytes}), nil
    61  }