func (c *Certifier) ObtainForCSR(request ObtainForCSRRequest) (*Resource, error) {
	if request.CSR == nil {
		return nil, errors.New("cannot obtain resource for CSR: CSR is missing")
	}
	domains := certcrypto.ExtractDomainsCSR(request.CSR)
	if request.Bundle {
		log.Infof("[%s] acme: Obtaining bundled SAN certificate given a CSR", strings.Join(domains, ", "))
	} else {
		log.Infof("[%s] acme: Obtaining SAN certificate given a CSR", strings.Join(domains, ", "))
	}
	order, err := c.core.Orders.New(domains)
	if err != nil {
		return nil, err
	}
	authz, err := c.getAuthorizations(order)
	if err != nil {
		c.deactivateAuthorizations(order, request.AlwaysDeactivateAuthorizations)
		return nil, err
	}
	err = c.resolver.Solve(authz)
	if err != nil {
		c.deactivateAuthorizations(order, request.AlwaysDeactivateAuthorizations)
		return nil, err
	}
	log.Infof("[%s] acme: Validations succeeded; requesting certificates", strings.Join(domains, ", "))
	failures := make(obtainError)
	cert, err := c.getForCSR(domains, order, request.Bundle, request.CSR.Raw, nil, request.PreferredChain)
	if err != nil {
		for _, auth := range authz {
			failures[challenge.GetTargetedDomain(auth)] = err
		}
	}
	if request.AlwaysDeactivateAuthorizations {
		c.deactivateAuthorizations(order, true)
	}
	if cert != nil {
		cert.CSR = certcrypto.PEMEncode(request.CSR)
	}
	if len(failures) > 0 {
		return cert, failures
	}
	return cert, nil
}
ObtainForCSR tries to obtain a certificate matching the CSR passed into it.

The domains are inferred from the CommonName and SubjectAltNames, if any.
The private key for this CSR is not required.

If bundle is true, the []byte contains both the issuer certificate and your issued certificate as a bundle.

This function will never return a partial certificate.
If one domain in the list fails, the whole certificate will fail.
package certificate
import (
	"bytes"
	"crypto"
	"crypto/x509"
	"encoding/base64"
	"errors"
	"fmt"
	"io"
	"net/http"
	"strings"
	"time"
	"github.com/go-acme/lego/v4/acme"
	"github.com/go-acme/lego/v4/acme/api"
	"github.com/go-acme/lego/v4/certcrypto"
	"github.com/go-acme/lego/v4/challenge"
	"github.com/go-acme/lego/v4/log"
	"github.com/go-acme/lego/v4/platform/wait"
	"golang.org/x/crypto/ocsp"
	"golang.org/x/net/idna"
)
const maxBodySize = 1024 * 1024
type Resource struct {
	Domain            string `json:"domain"`
	CertURL           string `json:"certUrl"`
	CertStableURL     string `json:"certStableUrl"`
	PrivateKey        []byte `json:"-"`
	Certificate       []byte `json:"-"`
	IssuerCertificate []byte `json:"-"`
	CSR               []byte `json:"-"`
}
type ObtainRequest struct {
	Domains                        []string
	Bundle                         bool
	PrivateKey                     crypto.PrivateKey
	MustStaple                     bool
	PreferredChain                 string
	AlwaysDeactivateAuthorizations bool
}
type ObtainForCSRRequest struct {
	CSR                            *x509.CertificateRequest
	Bundle                         bool
	PreferredChain                 string
	AlwaysDeactivateAuthorizations bool
}
type resolver interface {
	Solve(authorizations []acme.Authorization) error
}
type CertifierOptions struct {
	KeyType certcrypto.KeyType
	Timeout time.Duration
}
type Certifier struct {
	core     *api.Core
	resolver resolver
	options  CertifierOptions
}
func NewCertifier(core *api.Core, resolver resolver, options CertifierOptions) *Certifier {
	return &Certifier{
		core:     core,
		resolver: resolver,
		options:  options,
	}
}
func (c *Certifier) Obtain(request ObtainRequest) (*Resource, error) {
	if len(request.Domains) == 0 {
		return nil, errors.New("no domains to obtain a certificate for")
	}
	domains := sanitizeDomain(request.Domains)
	if request.Bundle {
		log.Infof("[%s] acme: Obtaining bundled SAN certificate", strings.Join(domains, ", "))
	} else {
		log.Infof("[%s] acme: Obtaining SAN certificate", strings.Join(domains, ", "))
	}
	order, err := c.core.Orders.New(domains)
	if err != nil {
		return nil, err
	}
	authz, err := c.getAuthorizations(order)
	if err != nil {
		c.deactivateAuthorizations(order, request.AlwaysDeactivateAuthorizations)
		return nil, err
	}
	err = c.resolver.Solve(authz)
	if err != nil {
		c.deactivateAuthorizations(order, request.AlwaysDeactivateAuthorizations)
		return nil, err
	}
	log.Infof("[%s] acme: Validations succeeded; requesting certificates", strings.Join(domains, ", "))
	failures := make(obtainError)
	cert, err := c.getForOrder(domains, order, request.Bundle, request.PrivateKey, request.MustStaple, request.PreferredChain)
	if err != nil {
		for _, auth := range authz {
			failures[challenge.GetTargetedDomain(auth)] = err
		}
	}
	if request.AlwaysDeactivateAuthorizations {
		c.deactivateAuthorizations(order, true)
	}
	if len(failures) > 0 {
		return cert, failures
	}
	return cert, nil
}