...

Source file src/github.com/letsencrypt/boulder/issuance/issuance.go

Documentation: github.com/letsencrypt/boulder/issuance

     1  package issuance
     2  
     3  import (
     4  	"bytes"
     5  	"crypto"
     6  	"crypto/ecdsa"
     7  	"crypto/elliptic"
     8  	"crypto/rand"
     9  	"crypto/rsa"
    10  	"crypto/sha1"
    11  	"crypto/sha256"
    12  	"crypto/x509"
    13  	"crypto/x509/pkix"
    14  	"encoding/asn1"
    15  	"encoding/json"
    16  	"errors"
    17  	"fmt"
    18  	"math/big"
    19  	"os"
    20  	"sync"
    21  	"time"
    22  
    23  	ct "github.com/google/certificate-transparency-go"
    24  	cttls "github.com/google/certificate-transparency-go/tls"
    25  	ctx509 "github.com/google/certificate-transparency-go/x509"
    26  	"github.com/jmhodges/clock"
    27  	"golang.org/x/crypto/ocsp"
    28  
    29  	"github.com/letsencrypt/boulder/config"
    30  	"github.com/letsencrypt/boulder/core"
    31  	"github.com/letsencrypt/boulder/linter"
    32  	"github.com/letsencrypt/boulder/precert"
    33  	"github.com/letsencrypt/boulder/privatekey"
    34  	"github.com/letsencrypt/pkcs11key/v4"
    35  )
    36  
    37  // ProfileConfig describes the certificate issuance constraints for all issuers.
    38  type ProfileConfig struct {
    39  	AllowMustStaple bool
    40  	AllowCTPoison   bool
    41  	AllowSCTList    bool
    42  	AllowCommonName bool
    43  
    44  	MaxValidityPeriod   config.Duration
    45  	MaxValidityBackdate config.Duration
    46  
    47  	// Deprecated: we do not respect this field.
    48  	Policies []PolicyConfig `validate:"-"`
    49  }
    50  
    51  // PolicyConfig describes a policy
    52  type PolicyConfig struct {
    53  	OID string `validate:"required"`
    54  }
    55  
    56  // IssuerConfig describes the constraints on and URLs used by a single issuer.
    57  type IssuerConfig struct {
    58  	UseForRSALeaves   bool
    59  	UseForECDSALeaves bool
    60  
    61  	IssuerURL string `validate:"required,url"`
    62  	OCSPURL   string `validate:"required,url"`
    63  	CRLURL    string `validate:"omitempty,url"`
    64  
    65  	Location IssuerLoc
    66  }
    67  
    68  // IssuerLoc describes the on-disk location and parameters that an issuer
    69  // should use to retrieve its certificate and private key.
    70  // Only one of File, ConfigFile, or PKCS11 should be set.
    71  type IssuerLoc struct {
    72  	// A file from which a private key will be read and parsed.
    73  	File string `validate:"required_without_all=ConfigFile PKCS11"`
    74  	// A file from which a pkcs11key.Config will be read and parsed, if File is not set.
    75  	ConfigFile string `validate:"required_without_all=PKCS11 File"`
    76  	// An in-memory pkcs11key.Config, which will be used if ConfigFile is not set.
    77  	PKCS11 *pkcs11key.Config `validate:"required_without_all=ConfigFile File"`
    78  	// A file from which a certificate will be read and parsed.
    79  	CertFile string `validate:"required"`
    80  	// Number of sessions to open with the HSM. For maximum performance,
    81  	// this should be equal to the number of cores in the HSM. Defaults to 1.
    82  	NumSessions int
    83  }
    84  
    85  // LoadIssuer loads a signer (private key) and certificate from the locations specified.
    86  func LoadIssuer(location IssuerLoc) (*Certificate, crypto.Signer, error) {
    87  	issuerCert, err := LoadCertificate(location.CertFile)
    88  	if err != nil {
    89  		return nil, nil, err
    90  	}
    91  
    92  	signer, err := loadSigner(location, issuerCert)
    93  	if err != nil {
    94  		return nil, nil, err
    95  	}
    96  
    97  	if !core.KeyDigestEquals(signer.Public(), issuerCert.PublicKey) {
    98  		return nil, nil, fmt.Errorf("Issuer key did not match issuer cert %s", location.CertFile)
    99  	}
   100  	return issuerCert, signer, err
   101  }
   102  
   103  func LoadCertificate(path string) (*Certificate, error) {
   104  	cert, err := core.LoadCert(path)
   105  	if err != nil {
   106  		return nil, err
   107  	}
   108  	return NewCertificate(cert)
   109  }
   110  
   111  func loadSigner(location IssuerLoc, cert *Certificate) (crypto.Signer, error) {
   112  	if location.File != "" {
   113  		signer, _, err := privatekey.Load(location.File)
   114  		if err != nil {
   115  			return nil, err
   116  		}
   117  		return signer, nil
   118  	}
   119  
   120  	var pkcs11Config *pkcs11key.Config
   121  	if location.ConfigFile != "" {
   122  		contents, err := os.ReadFile(location.ConfigFile)
   123  		if err != nil {
   124  			return nil, err
   125  		}
   126  		pkcs11Config = new(pkcs11key.Config)
   127  		err = json.Unmarshal(contents, pkcs11Config)
   128  		if err != nil {
   129  			return nil, err
   130  		}
   131  	} else {
   132  		pkcs11Config = location.PKCS11
   133  	}
   134  
   135  	if pkcs11Config.Module == "" ||
   136  		pkcs11Config.TokenLabel == "" ||
   137  		pkcs11Config.PIN == "" {
   138  		return nil, fmt.Errorf("missing a field in pkcs11Config %#v", pkcs11Config)
   139  	}
   140  
   141  	numSessions := location.NumSessions
   142  	if numSessions <= 0 {
   143  		numSessions = 1
   144  	}
   145  
   146  	return pkcs11key.NewPool(numSessions, pkcs11Config.Module,
   147  		pkcs11Config.TokenLabel, pkcs11Config.PIN, cert.PublicKey)
   148  }
   149  
   150  // Profile is the validated structure created by reading in ProfileConfigs and IssuerConfigs
   151  type Profile struct {
   152  	useForRSALeaves   bool
   153  	useForECDSALeaves bool
   154  
   155  	allowMustStaple bool
   156  	allowCTPoison   bool
   157  	allowSCTList    bool
   158  	allowCommonName bool
   159  
   160  	sigAlg    x509.SignatureAlgorithm
   161  	ocspURL   string
   162  	crlURL    string
   163  	issuerURL string
   164  
   165  	maxBackdate time.Duration
   166  	maxValidity time.Duration
   167  }
   168  
   169  // NewProfile synthesizes the profile config and issuer config into a single
   170  // object, and checks various aspects for correctness.
   171  func NewProfile(profileConfig ProfileConfig, issuerConfig IssuerConfig) (*Profile, error) {
   172  	if issuerConfig.IssuerURL == "" {
   173  		return nil, errors.New("Issuer URL is required")
   174  	}
   175  	if issuerConfig.OCSPURL == "" {
   176  		return nil, errors.New("OCSP URL is required")
   177  	}
   178  
   179  	sp := &Profile{
   180  		useForRSALeaves:   issuerConfig.UseForRSALeaves,
   181  		useForECDSALeaves: issuerConfig.UseForECDSALeaves,
   182  		allowMustStaple:   profileConfig.AllowMustStaple,
   183  		allowCTPoison:     profileConfig.AllowCTPoison,
   184  		allowSCTList:      profileConfig.AllowSCTList,
   185  		allowCommonName:   profileConfig.AllowCommonName,
   186  		issuerURL:         issuerConfig.IssuerURL,
   187  		crlURL:            issuerConfig.CRLURL,
   188  		ocspURL:           issuerConfig.OCSPURL,
   189  		maxBackdate:       profileConfig.MaxValidityBackdate.Duration,
   190  		maxValidity:       profileConfig.MaxValidityPeriod.Duration,
   191  	}
   192  
   193  	return sp, nil
   194  }
   195  
   196  // requestValid verifies the passed IssuanceRequest against the profile. If the
   197  // request doesn't match the signing profile an error is returned.
   198  func (p *Profile) requestValid(clk clock.Clock, req *IssuanceRequest) error {
   199  	switch req.PublicKey.(type) {
   200  	case *rsa.PublicKey:
   201  		if !p.useForRSALeaves {
   202  			return errors.New("cannot sign RSA public keys")
   203  		}
   204  	case *ecdsa.PublicKey:
   205  		if !p.useForECDSALeaves {
   206  			return errors.New("cannot sign ECDSA public keys")
   207  		}
   208  	default:
   209  		return errors.New("unsupported public key type")
   210  	}
   211  
   212  	if !p.allowMustStaple && req.IncludeMustStaple {
   213  		return errors.New("must-staple extension cannot be included")
   214  	}
   215  
   216  	if !p.allowCTPoison && req.IncludeCTPoison {
   217  		return errors.New("ct poison extension cannot be included")
   218  	}
   219  
   220  	if !p.allowSCTList && req.sctList != nil {
   221  		return errors.New("sct list extension cannot be included")
   222  	}
   223  
   224  	if req.IncludeCTPoison && req.sctList != nil {
   225  		return errors.New("cannot include both ct poison and sct list extensions")
   226  	}
   227  
   228  	if !p.allowCommonName && req.CommonName != "" {
   229  		return errors.New("common name cannot be included")
   230  	}
   231  
   232  	// The validity period is calculated inclusive of the whole second represented
   233  	// by the notAfter timestamp.
   234  	validity := req.NotAfter.Add(time.Second).Sub(req.NotBefore)
   235  	if validity <= 0 {
   236  		return errors.New("NotAfter must be after NotBefore")
   237  	}
   238  	if validity > p.maxValidity {
   239  		return fmt.Errorf("validity period is more than the maximum allowed period (%s>%s)", validity, p.maxValidity)
   240  	}
   241  	backdatedBy := clk.Now().Sub(req.NotBefore)
   242  	if backdatedBy > p.maxBackdate {
   243  		return fmt.Errorf("NotBefore is backdated more than the maximum allowed period (%s>%s)", backdatedBy, p.maxBackdate)
   244  	}
   245  	if backdatedBy < 0 {
   246  		return errors.New("NotBefore is in the future")
   247  	}
   248  
   249  	// We use 19 here because a 20-byte serial could produce >20 octets when
   250  	// encoded in ASN.1. That happens when the first byte is >0x80. See
   251  	// https://letsencrypt.org/docs/a-warm-welcome-to-asn1-and-der/#integer-encoding
   252  	if len(req.Serial) > 19 || len(req.Serial) < 9 {
   253  		return errors.New("serial must be between 9 and 19 bytes")
   254  	}
   255  
   256  	return nil
   257  }
   258  
   259  var defaultEKU = []x509.ExtKeyUsage{
   260  	x509.ExtKeyUsageServerAuth,
   261  	x509.ExtKeyUsageClientAuth,
   262  }
   263  
   264  func (p *Profile) generateTemplate() *x509.Certificate {
   265  	template := &x509.Certificate{
   266  		SignatureAlgorithm:    p.sigAlg,
   267  		ExtKeyUsage:           defaultEKU,
   268  		OCSPServer:            []string{p.ocspURL},
   269  		IssuingCertificateURL: []string{p.issuerURL},
   270  		BasicConstraintsValid: true,
   271  		// Baseline Requirements, Section 7.1.6.1: domain-validated
   272  		PolicyIdentifiers: []asn1.ObjectIdentifier{{2, 23, 140, 1, 2, 1}},
   273  	}
   274  
   275  	if p.crlURL != "" {
   276  		template.CRLDistributionPoints = []string{p.crlURL}
   277  	}
   278  
   279  	return template
   280  }
   281  
   282  // IssuerID is a statistically-unique small ID computed from a hash over the
   283  // entirety of the issuer certificate.
   284  // DEPRECATED: This identifier is being phased out in favor of IssuerNameID.
   285  // It exists in the database in certificateStatus rows for certs issued prior
   286  // to approximately November 2021, but is not being written for new rows.
   287  type IssuerID int64
   288  
   289  // IssuerNameID is a statistically-unique small ID which can be computed from
   290  // both CA and end-entity certs to link them together into a validation chain.
   291  // It is computed as a truncated hash over the issuer Subject Name bytes, or
   292  // over the end-entity's Issuer Name bytes, which are required to be equal.
   293  type IssuerNameID int64
   294  
   295  // Certificate embeds an *x509.Certificate and represents the added semantics
   296  // that this certificate can be used for issuance.
   297  type Certificate struct {
   298  	*x509.Certificate
   299  	id       IssuerID
   300  	nameID   IssuerNameID
   301  	nameHash [20]byte
   302  	keyHash  [20]byte
   303  }
   304  
   305  // NewCertificate wraps an in-memory cert in an issuance.Certificate, marking it
   306  // as an issuer cert. It may fail if the certificate does not contain the
   307  // attributes expected of an issuer certificate.
   308  func NewCertificate(ic *x509.Certificate) (*Certificate, error) {
   309  	res := Certificate{Certificate: ic}
   310  
   311  	// Compute ic.ID()
   312  	h := sha256.Sum256(ic.Raw)
   313  	res.id = IssuerID(big.NewInt(0).SetBytes(h[:4]).Int64())
   314  
   315  	// Compute ic.NameID()
   316  	res.nameID = truncatedHash(ic.RawSubject)
   317  
   318  	// Compute ic.NameHash()
   319  	res.nameHash = sha1.Sum(ic.RawSubject)
   320  
   321  	// Compute ic.KeyHash()
   322  	// The issuerKeyHash in OCSP requests is constructed over the DER encoding of
   323  	// the public key per RFC6960 (defined in RFC4055 for RSA and RFC5480 for
   324  	// ECDSA). We can't use MarshalPKIXPublicKey for this since it encodes keys
   325  	// using the SPKI structure itself, and we just want the contents of the
   326  	// subjectPublicKey for the hash, so we need to extract it ourselves.
   327  	var spki struct {
   328  		Algorithm pkix.AlgorithmIdentifier
   329  		PublicKey asn1.BitString
   330  	}
   331  	_, err := asn1.Unmarshal(ic.RawSubjectPublicKeyInfo, &spki)
   332  	if err != nil {
   333  		return nil, err
   334  	}
   335  	res.keyHash = sha1.Sum(spki.PublicKey.RightAlign())
   336  
   337  	return &res, nil
   338  }
   339  
   340  // ID returns the IssuerID (a truncated hash over the raw bytes of the whole
   341  // cert) of this issuer certificate.
   342  // DEPRECATED: Use .NameID() instead.
   343  func (ic *Certificate) ID() IssuerID {
   344  	return ic.id
   345  }
   346  
   347  // NameID returns the IssuerNameID (a truncated hash over the raw bytes of the
   348  // Subject Distinguished Name) of this issuer certificate. Useful for storing as
   349  // a lookup key in contexts that don't expect hash collisions.
   350  func (ic *Certificate) NameID() IssuerNameID {
   351  	return ic.nameID
   352  }
   353  
   354  // NameHash returns the SHA1 hash over the issuer certificate's Subject
   355  // Distinguished Name. This is one of the values used to uniquely identify the
   356  // issuer cert in an RFC6960 + RFC5019 OCSP request.
   357  func (ic *Certificate) NameHash() [20]byte {
   358  	return ic.nameHash
   359  }
   360  
   361  // KeyHash returns the SHA1 hash over the issuer certificate's Subject Public
   362  // Key Info. This is one of the values used to uniquely identify the issuer cert
   363  // in an RFC6960 + RFC5019 OCSP request.
   364  func (ic *Certificate) KeyHash() [20]byte {
   365  	return ic.keyHash
   366  }
   367  
   368  // GetIssuerNameID returns the IssuerNameID (a truncated hash over the raw bytes
   369  // of the Issuer Distinguished Name) of the given end-entity certificate.
   370  // Useful for performing lookups in contexts that don't expect hash collisions.
   371  func GetIssuerNameID(ee *x509.Certificate) IssuerNameID {
   372  	return truncatedHash(ee.RawIssuer)
   373  }
   374  
   375  // GetOCSPIssuerNameID returns the IssuerNameID (a truncated hash over the raw
   376  // bytes of the Responder Distinguished Name) of the given OCSP Response.
   377  // As per the OCSP spec, it is technically possible for this field to not be
   378  // populated: the OCSP Response can instead contain a SHA-1 hash of the Issuer
   379  // Public Key as the Responder ID. The Go stdlib always uses the DN, though.
   380  func GetOCSPIssuerNameID(resp *ocsp.Response) IssuerNameID {
   381  	return truncatedHash(resp.RawResponderName)
   382  }
   383  
   384  // truncatedHash computes a truncated SHA1 hash across arbitrary bytes. Uses
   385  // SHA1 because that is the algorithm most commonly used in OCSP requests.
   386  // PURPOSEFULLY NOT EXPORTED. Exists only to ensure that the implementations of
   387  // Certificate.NameID() and GetIssuerNameID() never diverge. Use those instead.
   388  func truncatedHash(name []byte) IssuerNameID {
   389  	h := crypto.SHA1.New()
   390  	h.Write(name)
   391  	s := h.Sum(nil)
   392  	return IssuerNameID(big.NewInt(0).SetBytes(s[:7]).Int64())
   393  }
   394  
   395  // Issuer is capable of issuing new certificates
   396  // TODO(#5086): make Cert and Signer private when they're no longer needed by ca.internalIssuer
   397  type Issuer struct {
   398  	Cert    *Certificate
   399  	Signer  crypto.Signer
   400  	Profile *Profile
   401  	Linter  *linter.Linter
   402  	Clk     clock.Clock
   403  }
   404  
   405  // NewIssuer constructs an Issuer on the heap, verifying that the profile
   406  // is well-formed.
   407  func NewIssuer(cert *Certificate, signer crypto.Signer, profile *Profile, linter *linter.Linter, clk clock.Clock) (*Issuer, error) {
   408  	switch k := cert.PublicKey.(type) {
   409  	case *rsa.PublicKey:
   410  		profile.sigAlg = x509.SHA256WithRSA
   411  	case *ecdsa.PublicKey:
   412  		switch k.Curve {
   413  		case elliptic.P256():
   414  			profile.sigAlg = x509.ECDSAWithSHA256
   415  		case elliptic.P384():
   416  			profile.sigAlg = x509.ECDSAWithSHA384
   417  		default:
   418  			return nil, fmt.Errorf("unsupported ECDSA curve: %s", k.Curve.Params().Name)
   419  		}
   420  	default:
   421  		return nil, errors.New("unsupported issuer key type")
   422  	}
   423  
   424  	if profile.useForRSALeaves || profile.useForECDSALeaves {
   425  		if cert.KeyUsage&x509.KeyUsageCertSign == 0 {
   426  			return nil, errors.New("end-entity signing cert does not have keyUsage certSign")
   427  		}
   428  	}
   429  	// TODO(#5086): Only do this check for ocsp-issuing issuers.
   430  	if cert.KeyUsage&x509.KeyUsageDigitalSignature == 0 {
   431  		return nil, errors.New("end-entity ocsp signing cert does not have keyUsage digitalSignature")
   432  	}
   433  
   434  	i := &Issuer{
   435  		Cert:    cert,
   436  		Signer:  signer,
   437  		Profile: profile,
   438  		Linter:  linter,
   439  		Clk:     clk,
   440  	}
   441  	return i, nil
   442  }
   443  
   444  // Algs provides the list of leaf certificate public key algorithms for which
   445  // this issuer is willing to issue. This is not necessarily the same as the
   446  // public key algorithm or signature algorithm in this issuer's own cert.
   447  func (i *Issuer) Algs() []x509.PublicKeyAlgorithm {
   448  	var algs []x509.PublicKeyAlgorithm
   449  	if i.Profile.useForRSALeaves {
   450  		algs = append(algs, x509.RSA)
   451  	}
   452  	if i.Profile.useForECDSALeaves {
   453  		algs = append(algs, x509.ECDSA)
   454  	}
   455  	return algs
   456  }
   457  
   458  // Name provides the Common Name specified in the issuer's certificate.
   459  func (i *Issuer) Name() string {
   460  	return i.Cert.Subject.CommonName
   461  }
   462  
   463  // ID provides a stable ID for an issuer's certificate. This is used for
   464  // identifying which issuer issued a certificate in the certificateStatus table.
   465  func (i *Issuer) ID() IssuerID {
   466  	return i.Cert.ID()
   467  }
   468  
   469  var ctPoisonExt = pkix.Extension{
   470  	// OID for CT poison, RFC 6962 (was never assigned a proper id-pe- name)
   471  	Id:       asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 3},
   472  	Value:    asn1.NullBytes,
   473  	Critical: true,
   474  }
   475  
   476  // OID for SCT list, RFC 6962 (was never assigned a proper id-pe- name)
   477  var sctListOID = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 2}
   478  
   479  func generateSCTListExt(scts []ct.SignedCertificateTimestamp) (pkix.Extension, error) {
   480  	list := ctx509.SignedCertificateTimestampList{}
   481  	for _, sct := range scts {
   482  		sctBytes, err := cttls.Marshal(sct)
   483  		if err != nil {
   484  			return pkix.Extension{}, err
   485  		}
   486  		list.SCTList = append(list.SCTList, ctx509.SerializedSCT{Val: sctBytes})
   487  	}
   488  	listBytes, err := cttls.Marshal(list)
   489  	if err != nil {
   490  		return pkix.Extension{}, err
   491  	}
   492  	extBytes, err := asn1.Marshal(listBytes)
   493  	if err != nil {
   494  		return pkix.Extension{}, err
   495  	}
   496  	return pkix.Extension{
   497  		Id:    sctListOID,
   498  		Value: extBytes,
   499  	}, nil
   500  }
   501  
   502  var mustStapleExt = pkix.Extension{
   503  	// RFC 7633: id-pe-tlsfeature OBJECT IDENTIFIER ::=  { id-pe 24 }
   504  	Id: asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 24},
   505  	// ASN.1 encoding of:
   506  	// SEQUENCE
   507  	//   INTEGER 5
   508  	// where "5" is the status_request feature (RFC 6066)
   509  	Value: []byte{0x30, 0x03, 0x02, 0x01, 0x05},
   510  }
   511  
   512  func generateSKID(pk crypto.PublicKey) ([]byte, error) {
   513  	pkBytes, err := x509.MarshalPKIXPublicKey(pk)
   514  	if err != nil {
   515  		return nil, err
   516  	}
   517  	var pkixPublicKey struct {
   518  		Algo      pkix.AlgorithmIdentifier
   519  		BitString asn1.BitString
   520  	}
   521  	if _, err := asn1.Unmarshal(pkBytes, &pkixPublicKey); err != nil {
   522  		return nil, err
   523  	}
   524  	skid := sha1.Sum(pkixPublicKey.BitString.Bytes)
   525  	return skid[:], nil
   526  }
   527  
   528  // IssuanceRequest describes a certificate issuance request
   529  type IssuanceRequest struct {
   530  	PublicKey crypto.PublicKey
   531  
   532  	Serial []byte
   533  
   534  	NotBefore time.Time
   535  	NotAfter  time.Time
   536  
   537  	CommonName string
   538  	DNSNames   []string
   539  
   540  	IncludeMustStaple bool
   541  	IncludeCTPoison   bool
   542  
   543  	// sctList is a list of SCTs to include in a final certificate.
   544  	// If it is non-empty, PrecertDER must also be non-empty.
   545  	sctList []ct.SignedCertificateTimestamp
   546  	// precertDER is the encoded bytes of the precertificate that a
   547  	// final certificate is expected to correspond to. If it is non-empty,
   548  	// SCTList must also be non-empty.
   549  	precertDER []byte
   550  }
   551  
   552  // An issuanceToken represents an assertion that Issuer.Lint has generated
   553  // a linting certificate for a given input and run the linter over it with no
   554  // errors. The token may be redeemed (at most once) to sign a certificate or
   555  // precertificate with the same Issuer's private key, containing the same
   556  // contents that were linted.
   557  type issuanceToken struct {
   558  	mu       sync.Mutex
   559  	template *x509.Certificate
   560  	pubKey   any
   561  	// A pointer to the issuer that created this token. This token may only
   562  	// be redeemed by the same issuer.
   563  	issuer *Issuer
   564  }
   565  
   566  // Prepare applies this Issuer's profile to create a template certificate. It
   567  // then generates a linting certificate from that template and runs the linter
   568  // over it. If successful, returns both the linting certificate (which can be
   569  // stored) and an issuanceToken. The issuanceToken can be used to sign a
   570  // matching certificate with this Issuer's private key.
   571  func (i *Issuer) Prepare(req *IssuanceRequest) ([]byte, *issuanceToken, error) {
   572  	// check request is valid according to the issuance profile
   573  	err := i.Profile.requestValid(i.Clk, req)
   574  	if err != nil {
   575  		return nil, nil, err
   576  	}
   577  
   578  	// generate template from the issuance profile
   579  	template := i.Profile.generateTemplate()
   580  
   581  	// populate template from the issuance request
   582  	template.NotBefore, template.NotAfter = req.NotBefore, req.NotAfter
   583  	template.SerialNumber = big.NewInt(0).SetBytes(req.Serial)
   584  	if req.CommonName != "" {
   585  		template.Subject.CommonName = req.CommonName
   586  	}
   587  	template.DNSNames = req.DNSNames
   588  	template.AuthorityKeyId = i.Cert.SubjectKeyId
   589  	skid, err := generateSKID(req.PublicKey)
   590  	if err != nil {
   591  		return nil, nil, err
   592  	}
   593  	template.SubjectKeyId = skid
   594  	switch req.PublicKey.(type) {
   595  	case *rsa.PublicKey:
   596  		template.KeyUsage = x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment
   597  	case *ecdsa.PublicKey:
   598  		template.KeyUsage = x509.KeyUsageDigitalSignature
   599  	}
   600  
   601  	if req.IncludeCTPoison {
   602  		template.ExtraExtensions = append(template.ExtraExtensions, ctPoisonExt)
   603  	} else if len(req.sctList) > 0 {
   604  		if len(req.precertDER) == 0 {
   605  			return nil, nil, errors.New("inconsistent request contains sctList but no precertDER")
   606  		}
   607  		sctListExt, err := generateSCTListExt(req.sctList)
   608  		if err != nil {
   609  			return nil, nil, err
   610  		}
   611  		template.ExtraExtensions = append(template.ExtraExtensions, sctListExt)
   612  	} else {
   613  		return nil, nil, errors.New("invalid request contains neither sctList nor precertDER")
   614  	}
   615  
   616  	if req.IncludeMustStaple {
   617  		template.ExtraExtensions = append(template.ExtraExtensions, mustStapleExt)
   618  	}
   619  
   620  	// check that the tbsCertificate is properly formed by signing it
   621  	// with a throwaway key and then linting it using zlint
   622  	lintCertBytes, err := i.Linter.Check(template, req.PublicKey)
   623  	if err != nil {
   624  		return nil, nil, fmt.Errorf("tbsCertificate linting failed: %w", err)
   625  	}
   626  
   627  	if len(req.precertDER) > 0 {
   628  		err = precert.Correspond(req.precertDER, lintCertBytes)
   629  		if err != nil {
   630  			return nil, nil, fmt.Errorf("precert does not correspond to linted final cert: %w", err)
   631  		}
   632  	}
   633  
   634  	token := &issuanceToken{sync.Mutex{}, template, req.PublicKey, i}
   635  	return lintCertBytes, token, nil
   636  }
   637  
   638  // Issue performs a real issuance using an issuanceToken resulting from a
   639  // previous call to Prepare(). Call this at most once per token. Calls after
   640  // the first will receive an error.
   641  func (i *Issuer) Issue(token *issuanceToken) ([]byte, error) {
   642  	if token == nil {
   643  		return nil, errors.New("nil issuanceToken")
   644  	}
   645  	token.mu.Lock()
   646  	defer token.mu.Unlock()
   647  	if token.template == nil {
   648  		return nil, errors.New("issuance token already redeemed")
   649  	}
   650  	template := token.template
   651  	token.template = nil
   652  
   653  	if token.issuer != i {
   654  		return nil, errors.New("tried to redeem issuance token with the wrong issuer")
   655  	}
   656  
   657  	return x509.CreateCertificate(rand.Reader, template, i.Cert.Certificate, token.pubKey, i.Signer)
   658  }
   659  
   660  func ContainsMustStaple(extensions []pkix.Extension) bool {
   661  	for _, ext := range extensions {
   662  		if ext.Id.Equal(mustStapleExt.Id) && bytes.Equal(ext.Value, mustStapleExt.Value) {
   663  			return true
   664  		}
   665  	}
   666  	return false
   667  }
   668  
   669  func containsCTPoison(extensions []pkix.Extension) bool {
   670  	for _, ext := range extensions {
   671  		if ext.Id.Equal(ctPoisonExt.Id) && bytes.Equal(ext.Value, asn1.NullBytes) {
   672  			return true
   673  		}
   674  	}
   675  	return false
   676  }
   677  
   678  // RequestFromPrecert constructs a final certificate IssuanceRequest matching
   679  // the provided precertificate. It returns an error if the precertificate doesn't
   680  // contain the CT poison extension.
   681  func RequestFromPrecert(precert *x509.Certificate, scts []ct.SignedCertificateTimestamp) (*IssuanceRequest, error) {
   682  	if !containsCTPoison(precert.Extensions) {
   683  		return nil, errors.New("provided certificate doesn't contain the CT poison extension")
   684  	}
   685  	return &IssuanceRequest{
   686  		PublicKey:         precert.PublicKey,
   687  		Serial:            precert.SerialNumber.Bytes(),
   688  		NotBefore:         precert.NotBefore,
   689  		NotAfter:          precert.NotAfter,
   690  		CommonName:        precert.Subject.CommonName,
   691  		DNSNames:          precert.DNSNames,
   692  		IncludeMustStaple: ContainsMustStaple(precert.Extensions),
   693  		sctList:           scts,
   694  		precertDER:        precert.Raw,
   695  	}, nil
   696  }
   697  
   698  // LoadChain takes a list of filenames containing pem-formatted certificates,
   699  // and returns a chain representing all of those certificates in order. It
   700  // ensures that the resulting chain is valid. The final file is expected to be
   701  // a root certificate, which the chain will be verified against, but which will
   702  // not be included in the resulting chain.
   703  func LoadChain(certFiles []string) ([]*Certificate, error) {
   704  	if len(certFiles) < 2 {
   705  		return nil, errors.New(
   706  			"each chain must have at least two certificates: an intermediate and a root")
   707  	}
   708  
   709  	// Pre-load all the certificates to make validation easier.
   710  	certs := make([]*Certificate, len(certFiles))
   711  	var err error
   712  	for i := 0; i < len(certFiles); i++ {
   713  		certs[i], err = LoadCertificate(certFiles[i])
   714  		if err != nil {
   715  			return nil, fmt.Errorf("failed to load certificate %q: %w", certFiles[i], err)
   716  		}
   717  	}
   718  
   719  	// Iterate over all certs except for the last, checking that their signature
   720  	// comes from the next cert in the list.
   721  	chain := make([]*Certificate, len(certFiles)-1)
   722  	for i := 0; i < len(certs)-1; i++ {
   723  		err = certs[i].CheckSignatureFrom(certs[i+1].Certificate)
   724  		if err != nil {
   725  			return nil, fmt.Errorf("failed to verify signature from %q to %q (%q to %q): %w",
   726  				certs[i+1].Subject, certs[i].Subject, certFiles[i+1], certFiles[i], err)
   727  		}
   728  		chain[i] = certs[i]
   729  	}
   730  
   731  	// Verify that the last cert is self-signed.
   732  	lastCert := certs[len(certs)-1]
   733  	err = lastCert.CheckSignatureFrom(lastCert.Certificate)
   734  	if err != nil {
   735  		return nil, fmt.Errorf(
   736  			"final cert in chain (%q; %q) must be self-signed (used only for validation): %w",
   737  			lastCert.Subject, certFiles[len(certFiles)-1], err)
   738  	}
   739  
   740  	return chain, nil
   741  }
   742  

View as plain text