func New()

in internal/certs/certs.go [155:238]


func New(certType int, issuer *Issuer, opts ...Option) (*Certificate, error) {
	key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	if err != nil {
		return nil, fmt.Errorf("failed to generate key: %w", err)
	}

	sn, err := newSerialNumber()
	if err != nil {
		return nil, fmt.Errorf("failed to get a unique serial number: %w", err)
	}

	// Don't use a expiration time longer than 825 days.
	// See https://rahulkj.github.io/openssl,/certificates/2022/09/09/self-signed-certificates.html.
	const longTime = 800 * 24 * time.Hour
	template := x509.Certificate{
		NotBefore: time.Now(),
		NotAfter:  time.Now().Add(longTime),

		SerialNumber:          sn,
		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
		BasicConstraintsValid: true,
	}

	switch certType {
	case IssueCertTypeCA:
		template.IsCA = true
		template.KeyUsage |= x509.KeyUsageCRLSign | x509.KeyUsageCertSign

		if issuer == nil {
			template.Subject.CommonName = "elastic-package CA"
		} else {
			template.Subject.CommonName = "intermediate elastic-package CA"
		}
	case IssueCertTypeClient:
		// If the requester is a client we set clientAuth instead
		template.ExtKeyUsage = []x509.ExtKeyUsage{
			x509.ExtKeyUsageClientAuth,
		}
		// Include local hostname and ips as alternates in service certificates.
		template.DNSNames = []string{"localhost"}
		template.IPAddresses = []net.IP{net.ParseIP("127.0.0.1"), net.ParseIP("::1")}
	case IssueCertTypeService:
		template.ExtKeyUsage = []x509.ExtKeyUsage{
			// Required for Chrome in OSX to show the "Proceed anyway" link.
			// https://stackoverflow.com/a/64309893/28855
			x509.ExtKeyUsageServerAuth,
		}
		// Include local hostname and ips as alternates in service certificates.
		template.DNSNames = []string{"localhost"}
		template.IPAddresses = []net.IP{net.ParseIP("127.0.0.1"), net.ParseIP("::1")}
	default:
		return nil, fmt.Errorf("unknown certificate type %d", certType)
	}

	for _, opt := range opts {
		opt(&template)
	}

	// Self-signed unless an issuer has been received.
	var parent *x509.Certificate = &template
	var signer crypto.Signer = key
	var issuerCert *Certificate
	if issuer != nil {
		parent = issuer.cert
		signer = issuer.key
		issuerCert = issuer.Certificate
		template.Issuer = issuer.cert.Subject
	}

	der, err := x509.CreateCertificate(rand.Reader, &template, parent, key.Public(), signer)
	if err != nil {
		return nil, fmt.Errorf("failed to generate certificate: %w", err)
	}
	cert, err := x509.ParseCertificate(der)
	if err != nil {
		return nil, fmt.Errorf("failed to parse certificate: %w", err)
	}

	return &Certificate{
		key:    key,
		cert:   cert,
		issuer: issuerCert,
	}, nil
}