diff --git a/authority/provisioner/scep.go b/authority/provisioner/scep.go index b6e8b925e..ce34d88c3 100644 --- a/authority/provisioner/scep.go +++ b/authority/provisioner/scep.go @@ -41,6 +41,10 @@ type SCEP struct { // GetCACerts response ExcludeIntermediate bool `json:"excludeIntermediate,omitempty"` + // ReturnEntireCertChain makes the provisioner return the full certificate chain + // provided by the CA rather than just the leaf certificate + ReturnEntireCertChain bool `json:"returnEntireCertChain,omitempty"` + // MinimumPublicKeyLength is the minimum length for public keys in CSRs MinimumPublicKeyLength int `json:"minimumPublicKeyLength,omitempty"` @@ -447,6 +451,13 @@ func (s *SCEP) ShouldIncludeIntermediateInChain() bool { return !s.ExcludeIntermediate } +// ShouldReturnEntireCertChain indicates if the +// CA should return the entire chain of certificates in the SCEP +// PKIOperation response rather than just the leaf certificate. +func (s *SCEP) ShouldReturnEntireCertChain() bool { + return s.ReturnEntireCertChain +} + // GetContentEncryptionAlgorithm returns the numeric identifier // for the pkcs7 package encryption algorithm to use. func (s *SCEP) GetContentEncryptionAlgorithm() int { diff --git a/scep/authority.go b/scep/authority.go index 256c540d0..40c1afc77 100644 --- a/scep/authority.go +++ b/scep/authority.go @@ -363,10 +363,16 @@ func (a *Authority) SignCSR(ctx context.Context, csr *x509.CertificateRequest, m return nil, err } - // add the certificate into the signed data type - // this cert must be added before the signedData because the recipient will expect it - // as the first certificate in the array - signedData.AddCertificate(cert) + // add the certificate chain into the signed data type if specified + // otherwise just return the leaf cert. the ordering of the added signed data is important + // because the recipient will expect the leaf as the first certificate + if p.ShouldReturnEntireCertChain() { + for _, c := range certChain { + signedData.AddCertificate(c) + } + } else { + signedData.AddCertificate(cert) + } signerCert, signer, err := a.selectSigner(ctx) if err != nil { diff --git a/scep/provisioner.go b/scep/provisioner.go index 35821d8cc..1c0f06792 100644 --- a/scep/provisioner.go +++ b/scep/provisioner.go @@ -17,6 +17,7 @@ type Provisioner interface { GetCapabilities() []string ShouldIncludeRootInChain() bool ShouldIncludeIntermediateInChain() bool + ShouldReturnEntireCertChain() bool GetDecrypter() (*x509.Certificate, crypto.Decrypter) GetSigner() (*x509.Certificate, crypto.Signer) GetContentEncryptionAlgorithm() int