package ca

import (
	"bytes"
	"context"
	"crypto"
	"crypto/ecdsa"
	"crypto/elliptic"
	cryptorand "crypto/rand"
	"crypto/rsa"
	"crypto/tls"
	"crypto/x509"
	"encoding/asn1"
	"encoding/pem"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"time"

	cfcsr "github.com/cloudflare/cfssl/csr"
	"github.com/cloudflare/cfssl/helpers"
	"github.com/cloudflare/cfssl/initca"
	cflog "github.com/cloudflare/cfssl/log"
	cfsigner "github.com/cloudflare/cfssl/signer"
	"github.com/cloudflare/cfssl/signer/local"
	"github.com/docker/go-events"
	"github.com/docker/swarmkit/api"
	"github.com/docker/swarmkit/ca/pkcs8"
	"github.com/docker/swarmkit/connectionbroker"
	"github.com/docker/swarmkit/ioutils"
	"github.com/opencontainers/go-digest"
	"github.com/pkg/errors"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/status"
)

const (
	// Security Strength Equivalence
	//-----------------------------------
	//| ECC  |  DH/DSA/RSA  |
	//| 256  |     3072     |
	//| 384  |     7680     |
	//-----------------------------------

	// RootKeySize is the default size of the root CA key
	// It would be ideal for the root key to use P-384, but in P-384 is not optimized in go yet :(
	RootKeySize = 256
	// RootKeyAlgo defines the default algorithm for the root CA Key
	RootKeyAlgo = "ecdsa"
	// RootCAExpiration represents the default expiration for the root CA in seconds (20 years)
	RootCAExpiration = "630720000s"
	// DefaultNodeCertExpiration represents the default expiration for node certificates (3 months)
	DefaultNodeCertExpiration = 2160 * time.Hour
	// CertBackdate represents the amount of time each certificate is backdated to try to avoid
	// clock drift issues.
	CertBackdate = 1 * time.Hour
	// CertLowerRotationRange represents the minimum fraction of time that we will wait when randomly
	// choosing our next certificate rotation
	CertLowerRotationRange = 0.5
	// CertUpperRotationRange represents the maximum fraction of time that we will wait when randomly
	// choosing our next certificate rotation
	CertUpperRotationRange = 0.8
	// MinNodeCertExpiration represents the minimum expiration for node certificates
	MinNodeCertExpiration = 1 * time.Hour
)

// BasicConstraintsOID is the ASN1 Object ID indicating a basic constraints extension
var BasicConstraintsOID = asn1.ObjectIdentifier{2, 5, 29, 19}

// A recoverableErr is a non-fatal error encountered signing a certificate,
// which means that the certificate issuance may be retried at a later time.
type recoverableErr struct {
	err error
}

func (r recoverableErr) Error() string {
	return r.err.Error()
}

// ErrNoLocalRootCA is an error type used to indicate that the local root CA
// certificate file does not exist.
var ErrNoLocalRootCA = errors.New("local root CA certificate does not exist")

// ErrNoValidSigner is an error type used to indicate that our RootCA doesn't have the ability to
// sign certificates.
var ErrNoValidSigner = recoverableErr{err: errors.New("no valid signer found")}

func init() {
	cflog.Level = 5
}

// CertPaths is a helper struct that keeps track of the paths of a
// Cert and corresponding Key
type CertPaths struct {
	Cert, Key string
}

// IssuerInfo contains the subject and public key of the issuer of a certificate
type IssuerInfo struct {
	Subject   []byte
	PublicKey []byte
}

// LocalSigner is a signer that can sign CSRs
type LocalSigner struct {
	cfsigner.Signer

	// Key will only be used by the original manager to put the private
	// key-material in raft, no signing operations depend on it.
	Key []byte

	// Cert is one PEM encoded Certificate used as the signing CA.  It must correspond to the key.
	Cert []byte

	// just cached parsed values for validation, etc.
	parsedCert   *x509.Certificate
	cryptoSigner crypto.Signer
}

type x509UnknownAuthError struct {
	error
	failedLeafCert *x509.Certificate
}

// RootCA is the representation of everything we need to sign certificates and/or to verify certificates
//
// RootCA.Cert:          [CA cert1][CA cert2]
// RootCA.Intermediates: [intermediate CA1][intermediate CA2][intermediate CA3]
// RootCA.signer.Cert:   [signing CA cert]
// RootCA.signer.Key:    [signing CA key]
//
// Requirements:
//
// - [signing CA key] must be the private key for [signing CA cert], and either both or none must be provided
//
// - [intermediate CA1] must have the same public key and subject as [signing CA cert], because otherwise when
//   appended to a leaf certificate, the intermediates will not form a chain (because [intermediate CA1] won't because
//   the signer of the leaf certificate)
// - [intermediate CA1] must be signed by [intermediate CA2], which must be signed by [intermediate CA3]
//
// - When we issue a certificate, the intermediates will be appended so that the certificate looks like:
//   [leaf signed by signing CA cert][intermediate CA1][intermediate CA2][intermediate CA3]
// - [leaf signed by signing CA cert][intermediate CA1][intermediate CA2][intermediate CA3] is guaranteed to form a
//   valid chain from [leaf signed by signing CA cert] to one of the root certs ([signing CA cert], [CA cert1], [CA cert2])
//   using zero or more of the intermediate certs ([intermediate CA1][intermediate CA2][intermediate CA3]) as intermediates
//
// Example 1:  Simple root rotation
// - Initial state:
// 	 - RootCA.Cert:          [Root CA1 self-signed]
// 	 - RootCA.Intermediates: []
// 	 - RootCA.signer.Cert:   [Root CA1 self-signed]
// 	 - Issued TLS cert:      [leaf signed by Root CA1]
//
// - Intermediate state (during root rotation):
//   - RootCA.Cert:          [Root CA1 self-signed]
//   - RootCA.Intermediates: [Root CA2 signed by Root CA1]
//   - RootCA.signer.Cert:   [Root CA2 signed by Root CA1]
//   - Issued TLS cert:      [leaf signed by Root CA2][Root CA2 signed by Root CA1]
//
// - Final state:
//   - RootCA.Cert:          [Root CA2 self-signed]
//   - RootCA.Intermediates: []
//   - RootCA.signer.Cert:   [Root CA2 self-signed]
//   - Issued TLS cert:      [leaf signed by Root CA2]
//
type RootCA struct {
	// Certs contains a bundle of self-signed, PEM encoded certificates for the Root CA to be used
	// as the root of trust.
	Certs []byte

	// Intermediates contains a bundle of PEM encoded intermediate CA certificates to append to any
	// issued TLS (leaf) certificates. The first one must have the same public key and subject as the
	// signing root certificate, and the rest must form a chain, each one certifying the one above it,
	// as per RFC5246 section 7.4.2.
	Intermediates []byte

	// Pool is the root pool used to validate TLS certificates
	Pool *x509.CertPool

	// Digest of the serialized bytes of the certificate(s)
	Digest digest.Digest

	// This signer will be nil if the node doesn't have the appropriate key material
	signer *LocalSigner
}

// Signer is an accessor for the local signer that returns an error if this root cannot sign.
func (rca *RootCA) Signer() (*LocalSigner, error) {
	if rca.Pool == nil || rca.signer == nil || len(rca.signer.Cert) == 0 || rca.signer.Signer == nil {
		return nil, ErrNoValidSigner
	}

	return rca.signer, nil
}

// IssueAndSaveNewCertificates generates a new key-pair, signs it with the local root-ca, and returns a
// TLS certificate and the issuer information for the certificate.
func (rca *RootCA) IssueAndSaveNewCertificates(kw KeyWriter, cn, ou, org string) (*tls.Certificate, *IssuerInfo, error) {
	csr, key, err := GenerateNewCSR()
	if err != nil {
		return nil, nil, errors.Wrap(err, "error when generating new node certs")
	}

	// Obtain a signed Certificate
	certChain, err := rca.ParseValidateAndSignCSR(csr, cn, ou, org)
	if err != nil {
		return nil, nil, errors.Wrap(err, "failed to sign node certificate")
	}
	signer, err := rca.Signer()
	if err != nil { // should never happen, since if ParseValidateAndSignCSR did not fail this root CA must have a signer
		return nil, nil, err
	}

	// Create a valid TLSKeyPair out of the PEM encoded private key and certificate
	tlsKeyPair, err := tls.X509KeyPair(certChain, key)
	if err != nil {
		return nil, nil, err
	}

	if err := kw.Write(NormalizePEMs(certChain), key, nil); err != nil {
		return nil, nil, err
	}

	return &tlsKeyPair, &IssuerInfo{
		PublicKey: signer.parsedCert.RawSubjectPublicKeyInfo,
		Subject:   signer.parsedCert.RawSubject,
	}, nil
}

// RequestAndSaveNewCertificates gets new certificates issued, either by signing them locally if a signer is
// available, or by requesting them from the remote server at remoteAddr.  This function returns the TLS
// certificate and the issuer information for the certificate.
func (rca *RootCA) RequestAndSaveNewCertificates(ctx context.Context, kw KeyWriter, config CertificateRequestConfig) (*tls.Certificate, *IssuerInfo, error) {
	// Create a new key/pair and CSR
	csr, key, err := GenerateNewCSR()
	if err != nil {
		return nil, nil, errors.Wrap(err, "error when generating new node certs")
	}

	// Get the remote manager to issue a CA signed certificate for this node
	// Retry up to 5 times in case the manager we first try to contact isn't
	// responding properly (for example, it may have just been demoted).
	var signedCert []byte
	for i := 0; i != 5; i++ {
		signedCert, err = GetRemoteSignedCertificate(ctx, csr, rca.Pool, config)
		if err == nil {
			break
		}

		// If the first attempt fails, we should try a remote
		// connection. The local node may be a manager that was
		// demoted, so the local connection (which is preferred) may
		// not work. If we are successful in renewing the certificate,
		// the local connection will not be returned by the connection
		// broker anymore.
		config.ForceRemote = true

		// Wait a moment, in case a leader election was taking place.
		select {
		case <-time.After(config.RetryInterval):
		case <-ctx.Done():
			return nil, nil, ctx.Err()
		}
	}
	if err != nil {
		return nil, nil, err
	}

	// Доверяй, но проверяй.
	// Before we overwrite our local key + certificate, let's make sure the server gave us one that is valid
	// Create an X509Cert so we can .Verify()
	// Check to see if this certificate was signed by our CA, and isn't expired
	parsedCerts, chains, err := ValidateCertChain(rca.Pool, signedCert, false)
	// TODO(cyli): - right now we need the invalid certificate in order to determine whether or not we should
	// download a new root, because we only want to do that in the case of workers.  When we have a single
	// codepath for updating the root CAs for both managers and workers, this snippet can go.
	if _, ok := err.(x509.UnknownAuthorityError); ok {
		if parsedCerts, parseErr := helpers.ParseCertificatesPEM(signedCert); parseErr == nil && len(parsedCerts) > 0 {
			return nil, nil, x509UnknownAuthError{
				error:          err,
				failedLeafCert: parsedCerts[0],
			}
		}
	}
	if err != nil {
		return nil, nil, err
	}

	// ValidateChain, if successful, will always return at least 1 parsed cert and at least 1 chain containing
	// at least 2 certificates:  the leaf and the root.
	leafCert := parsedCerts[0]
	issuer := chains[0][1]

	// Create a valid TLSKeyPair out of the PEM encoded private key and certificate
	tlsKeyPair, err := tls.X509KeyPair(signedCert, key)
	if err != nil {
		return nil, nil, err
	}

	var kekUpdate *KEKData
	for i := 0; i < 5; i++ {
		// ValidateCertChain will always return at least 1 cert, so indexing at 0 is safe
		kekUpdate, err = rca.getKEKUpdate(ctx, leafCert, tlsKeyPair, config)
		if err == nil {
			break
		}

		config.ForceRemote = true

		// Wait a moment, in case a leader election was taking place.
		select {
		case <-time.After(config.RetryInterval):
		case <-ctx.Done():
			return nil, nil, ctx.Err()
		}
	}
	if err != nil {
		return nil, nil, err
	}

	if err := kw.Write(NormalizePEMs(signedCert), key, kekUpdate); err != nil {
		return nil, nil, err
	}

	return &tlsKeyPair, &IssuerInfo{
		PublicKey: issuer.RawSubjectPublicKeyInfo,
		Subject:   issuer.RawSubject,
	}, nil
}

func (rca *RootCA) getKEKUpdate(ctx context.Context, leafCert *x509.Certificate, keypair tls.Certificate, config CertificateRequestConfig) (*KEKData, error) {
	var managerRole bool
	for _, ou := range leafCert.Subject.OrganizationalUnit {
		if ou == ManagerRole {
			managerRole = true
			break
		}
	}

	if managerRole {
		mtlsCreds := credentials.NewTLS(&tls.Config{ServerName: CARole, RootCAs: rca.Pool, Certificates: []tls.Certificate{keypair}})
		conn, err := getGRPCConnection(mtlsCreds, config.ConnBroker, config.ForceRemote)
		if err != nil {
			return nil, err
		}

		client := api.NewCAClient(conn.ClientConn)
		ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
		defer cancel()
		response, err := client.GetUnlockKey(ctx, &api.GetUnlockKeyRequest{})
		if err != nil {
			s, _ := status.FromError(err)
			if s.Code() == codes.Unimplemented { // if the server does not support keks, return as if no encryption key was specified
				conn.Close(true)
				return &KEKData{}, nil
			}

			conn.Close(false)
			return nil, err
		}
		conn.Close(true)
		return &KEKData{KEK: response.UnlockKey, Version: response.Version.Index}, nil
	}

	// If this is a worker, set to never encrypt. We always want to set to the lock key to nil,
	// in case this was a manager that was demoted to a worker.
	return &KEKData{}, nil
}

// PrepareCSR creates a CFSSL Sign Request based on the given raw CSR and
// overrides the Subject and Hosts with the given extra args.
func PrepareCSR(csrBytes []byte, cn, ou, org string) cfsigner.SignRequest {
	// All managers get added the subject-alt-name of CA, so they can be
	// used for cert issuance.
	hosts := []string{ou, cn}
	if ou == ManagerRole {
		hosts = append(hosts, CARole)
	}

	return cfsigner.SignRequest{
		Request: string(csrBytes),
		// OU is used for Authentication of the node type. The CN has the random
		// node ID.
		Subject: &cfsigner.Subject{CN: cn, Names: []cfcsr.Name{{OU: ou, O: org}}},
		// Adding ou as DNS alt name, so clients can connect to ManagerRole and CARole
		Hosts: hosts,
	}
}

// ParseValidateAndSignCSR returns a signed certificate from a particular rootCA and a CSR.
func (rca *RootCA) ParseValidateAndSignCSR(csrBytes []byte, cn, ou, org string) ([]byte, error) {
	signRequest := PrepareCSR(csrBytes, cn, ou, org)
	signer, err := rca.Signer()
	if err != nil {
		return nil, err
	}
	cert, err := signer.Sign(signRequest)
	if err != nil {
		return nil, errors.Wrap(err, "failed to sign node certificate")
	}

	return append(cert, rca.Intermediates...), nil
}

// CrossSignCACertificate takes a CA root certificate and generates an intermediate CA from it signed with the current root signer
func (rca *RootCA) CrossSignCACertificate(otherCAPEM []byte) ([]byte, error) {
	signer, err := rca.Signer()
	if err != nil {
		return nil, err
	}

	// create a new cert with exactly the same parameters, including the public key and exact NotBefore and NotAfter
	template, err := helpers.ParseCertificatePEM(otherCAPEM)
	if err != nil {
		return nil, errors.New("could not parse new CA certificate")
	}

	if !template.IsCA {
		return nil, errors.New("certificate not a CA")
	}

	template.SignatureAlgorithm = signer.parsedCert.SignatureAlgorithm // make sure we can sign with the signer key
	derBytes, err := x509.CreateCertificate(cryptorand.Reader, template, signer.parsedCert, template.PublicKey, signer.cryptoSigner)
	if err != nil {
		return nil, errors.Wrap(err, "could not cross-sign new CA certificate using old CA material")
	}

	return pem.EncodeToMemory(&pem.Block{
		Type:  "CERTIFICATE",
		Bytes: derBytes,
	}), nil
}

func validateSignatureAlgorithm(cert *x509.Certificate) error {
	switch cert.SignatureAlgorithm {
	case x509.SHA256WithRSA, x509.SHA384WithRSA, x509.SHA512WithRSA, x509.ECDSAWithSHA256, x509.ECDSAWithSHA384, x509.ECDSAWithSHA512:
		return nil
	default:
		return fmt.Errorf("unsupported signature algorithm: %s", cert.SignatureAlgorithm.String())
	}
}

// NewRootCA creates a new RootCA object from unparsed PEM cert bundle and key byte
// slices. key may be nil, and in this case NewRootCA will return a RootCA
// without a signer.
func NewRootCA(rootCertBytes, signCertBytes, signKeyBytes []byte, certExpiry time.Duration, intermediates []byte) (RootCA, error) {
	// Parse all the certificates in the cert bundle
	parsedCerts, err := helpers.ParseCertificatesPEM(rootCertBytes)
	if err != nil {
		return RootCA{}, errors.Wrap(err, "invalid root certificates")
	}
	// Check to see if we have at least one valid cert
	if len(parsedCerts) < 1 {
		return RootCA{}, errors.New("no valid root CA certificates found")
	}

	// Create a Pool with all of the certificates found
	pool := x509.NewCertPool()
	for _, cert := range parsedCerts {
		if err := validateSignatureAlgorithm(cert); err != nil {
			return RootCA{}, err
		}
		// Check to see if all of the certificates are valid, self-signed root CA certs
		selfpool := x509.NewCertPool()
		selfpool.AddCert(cert)
		if _, err := cert.Verify(x509.VerifyOptions{Roots: selfpool}); err != nil {
			return RootCA{}, errors.Wrap(err, "error while validating Root CA Certificate")
		}
		pool.AddCert(cert)
	}

	// Calculate the digest for our Root CA bundle
	digest := digest.FromBytes(rootCertBytes)

	// The intermediates supplied must be able to chain up to the root certificates, so that when they are appended to
	// a leaf certificate, the leaf certificate can be validated through the intermediates to the root certificates.
	var intermediatePool *x509.CertPool
	var parsedIntermediates []*x509.Certificate
	if len(intermediates) > 0 {
		parsedIntermediates, _, err = ValidateCertChain(pool, intermediates, false)
		if err != nil {
			return RootCA{}, errors.Wrap(err, "invalid intermediate chain")
		}
		intermediatePool = x509.NewCertPool()
		for _, cert := range parsedIntermediates {
			intermediatePool.AddCert(cert)
		}
	}

	var localSigner *LocalSigner
	if len(signKeyBytes) != 0 || len(signCertBytes) != 0 {
		localSigner, err = newLocalSigner(signKeyBytes, signCertBytes, certExpiry, pool, intermediatePool)
		if err != nil {
			return RootCA{}, err
		}

		// If a signer is provided and there are intermediates, then either the first intermediate would be the signer CA
		// certificate (in which case it'd have the same subject and public key), or it would be a cross-signed
		// intermediate with the same subject and public key as our signing CA certificate (which could be either an
		// intermediate cert or a self-signed root cert).
		if len(parsedIntermediates) > 0 && (!bytes.Equal(parsedIntermediates[0].RawSubject, localSigner.parsedCert.RawSubject) ||
			!bytes.Equal(parsedIntermediates[0].RawSubjectPublicKeyInfo, localSigner.parsedCert.RawSubjectPublicKeyInfo)) {
			return RootCA{}, errors.New(
				"invalid intermediate chain - the first intermediate must have the same subject and public key as the signing cert")
		}
	}

	return RootCA{signer: localSigner, Intermediates: intermediates, Digest: digest, Certs: rootCertBytes, Pool: pool}, nil
}

// ValidateCertChain checks checks that the certificates provided chain up to the root pool provided.  In addition
// it also enforces that every cert in the bundle certificates form a chain, each one certifying the one above,
// as per RFC5246 section 7.4.2, and that every certificate (whether or not it is necessary to form a chain to the root
// pool) is currently valid and not yet expired (unless allowExpiry is set to true).
// This is additional validation not required by go's Certificate.Verify (which allows invalid certs in the
// intermediate pool), because this function is intended to be used when reading certs from untrusted locations such as
// from disk or over a network when a CSR is signed, so it is extra pedantic.
// This function always returns all the parsed certificates in the bundle in order, which means there will always be
// at least 1 certificate if there is no error, and the valid chains found by Certificate.Verify
func ValidateCertChain(rootPool *x509.CertPool, certs []byte, allowExpired bool) ([]*x509.Certificate, [][]*x509.Certificate, error) {
	// Parse all the certificates in the cert bundle
	parsedCerts, err := helpers.ParseCertificatesPEM(certs)
	if err != nil {
		return nil, nil, err
	}
	if len(parsedCerts) == 0 {
		return nil, nil, errors.New("no certificates to validate")
	}
	now := time.Now()
	// ensure that they form a chain, each one being signed by the one after it
	var intermediatePool *x509.CertPool
	for i, cert := range parsedCerts {
		// Manual expiry validation because we want more information on which certificate in the chain is expired, and
		// because this is an easier way to allow expired certs.
		if now.Before(cert.NotBefore) {
			return nil, nil, errors.Wrapf(
				x509.CertificateInvalidError{
					Cert:   cert,
					Reason: x509.Expired,
				},
				"certificate (%d - %s) not valid before %s, and it is currently %s",
				i+1, cert.Subject.CommonName, cert.NotBefore.UTC().Format(time.RFC1123), now.Format(time.RFC1123))
		}
		if !allowExpired && now.After(cert.NotAfter) {
			return nil, nil, errors.Wrapf(
				x509.CertificateInvalidError{
					Cert:   cert,
					Reason: x509.Expired,
				},
				"certificate (%d - %s) not valid after %s, and it is currently %s",
				i+1, cert.Subject.CommonName, cert.NotAfter.UTC().Format(time.RFC1123), now.Format(time.RFC1123))
		}

		if i > 0 {
			// check that the previous cert was signed by this cert
			prevCert := parsedCerts[i-1]
			if err := prevCert.CheckSignatureFrom(cert); err != nil {
				return nil, nil, errors.Wrapf(err, "certificates do not form a chain: (%d - %s) is not signed by (%d - %s)",
					i, prevCert.Subject.CommonName, i+1, cert.Subject.CommonName)
			}

			if intermediatePool == nil {
				intermediatePool = x509.NewCertPool()
			}
			intermediatePool.AddCert(cert)

		}
	}

	verifyOpts := x509.VerifyOptions{
		Roots:         rootPool,
		Intermediates: intermediatePool,
		CurrentTime:   now,
	}

	var chains [][]*x509.Certificate

	// If we accept expired certs, try to build a valid cert chain using some subset of the certs.  We start off using the
	// first certificate's NotAfter as the current time, thus ensuring that the first cert is not expired. If the chain
	// still fails to validate due to expiry issues, continue iterating over the rest of the certs.
	// If any of the other certs has an earlier NotAfter time, use that time as the current time instead. This insures that
	// particular cert, and any that came before it, are not expired.  Note that the root that the certs chain up to
	// should also not be expired at that "current" time.
	if allowExpired {
		verifyOpts.CurrentTime = parsedCerts[0].NotAfter.Add(time.Hour)
		for _, cert := range parsedCerts {
			if !cert.NotAfter.Before(verifyOpts.CurrentTime) {
				continue
			}
			verifyOpts.CurrentTime = cert.NotAfter

			chains, err = parsedCerts[0].Verify(verifyOpts)
			if err == nil {
				return parsedCerts, chains, nil
			}
		}
		if invalid, ok := err.(x509.CertificateInvalidError); ok && invalid.Reason == x509.Expired {
			return nil, nil, errors.New("there is no time span for which all of the certificates, including a root, are valid")
		}
		return nil, nil, err
	}

	chains, err = parsedCerts[0].Verify(verifyOpts)
	if err != nil {
		return nil, nil, err
	}
	return parsedCerts, chains, nil
}

// newLocalSigner validates the signing cert and signing key to create a local signer, which accepts a crypto signer and a cert
func newLocalSigner(keyBytes, certBytes []byte, certExpiry time.Duration, rootPool, intermediatePool *x509.CertPool) (*LocalSigner, error) {
	if len(keyBytes) == 0 || len(certBytes) == 0 {
		return nil, errors.New("must provide both a signing key and a signing cert, or neither")
	}

	parsedCerts, err := helpers.ParseCertificatesPEM(certBytes)
	if err != nil {
		return nil, errors.Wrap(err, "invalid signing CA cert")
	}
	if len(parsedCerts) == 0 {
		return nil, errors.New("no valid signing CA certificates found")
	}
	if err := validateSignatureAlgorithm(parsedCerts[0]); err != nil {
		return nil, err
	}
	opts := x509.VerifyOptions{
		Roots:         rootPool,
		Intermediates: intermediatePool,
	}
	if _, err := parsedCerts[0].Verify(opts); err != nil {
		return nil, errors.Wrap(err, "error while validating signing CA certificate against roots and intermediates")
	}

	// The key should not be encrypted, but it could be in PKCS8 format rather than PKCS1
	priv, err := helpers.ParsePrivateKeyPEM(keyBytes)
	if err != nil {
		return nil, errors.Wrap(err, "malformed private key")
	}

	// We will always use the first certificate inside of the root bundle as the active one
	if err := ensureCertKeyMatch(parsedCerts[0], priv.Public()); err != nil {
		return nil, err
	}

	signer, err := local.NewSigner(priv, parsedCerts[0], cfsigner.DefaultSigAlgo(priv), SigningPolicy(certExpiry))
	if err != nil {
		return nil, err
	}

	return &LocalSigner{Cert: certBytes, Key: keyBytes, Signer: signer, parsedCert: parsedCerts[0], cryptoSigner: priv}, nil
}

func ensureCertKeyMatch(cert *x509.Certificate, key crypto.PublicKey) error {
	switch certPub := cert.PublicKey.(type) {
	case *rsa.PublicKey:
		if certPub.N.BitLen() < 2048 || certPub.E == 1 {
			return errors.New("unsupported RSA key parameters")
		}
		rsaKey, ok := key.(*rsa.PublicKey)
		if ok && certPub.E == rsaKey.E && certPub.N.Cmp(rsaKey.N) == 0 {
			return nil
		}
	case *ecdsa.PublicKey:
		switch certPub.Curve {
		case elliptic.P256(), elliptic.P384(), elliptic.P521():
			break
		default:
			return errors.New("unsupported ECDSA key parameters")
		}

		ecKey, ok := key.(*ecdsa.PublicKey)
		if ok && certPub.X.Cmp(ecKey.X) == 0 && certPub.Y.Cmp(ecKey.Y) == 0 {
			return nil
		}
	default:
		return errors.New("unknown or unsupported certificate public key algorithm")
	}

	return errors.New("certificate key mismatch")
}

// GetLocalRootCA validates if the contents of the file are a valid self-signed
// CA certificate, and returns the PEM-encoded Certificate if so
func GetLocalRootCA(paths CertPaths) (RootCA, error) {
	// Check if we have a Certificate file
	cert, err := ioutil.ReadFile(paths.Cert)
	if err != nil {
		if os.IsNotExist(err) {
			err = ErrNoLocalRootCA
		}

		return RootCA{}, err
	}
	signingCert := cert

	key, err := ioutil.ReadFile(paths.Key)
	if err != nil {
		if !os.IsNotExist(err) {
			return RootCA{}, err
		}
		// There may not be a local key. It's okay to pass in a nil
		// key. We'll get a root CA without a signer.
		key = nil
		signingCert = nil
	}

	return NewRootCA(cert, signingCert, key, DefaultNodeCertExpiration, nil)
}

func getGRPCConnection(creds credentials.TransportCredentials, connBroker *connectionbroker.Broker, forceRemote bool) (*connectionbroker.Conn, error) {
	dialOpts := []grpc.DialOption{
		grpc.WithTransportCredentials(creds),
		grpc.WithTimeout(5 * time.Second),
		grpc.WithBackoffMaxDelay(5 * time.Second),
	}
	if forceRemote {
		return connBroker.SelectRemote(dialOpts...)
	}
	return connBroker.Select(dialOpts...)
}

// GetRemoteCA returns the remote endpoint's CA certificate bundle
func GetRemoteCA(ctx context.Context, d digest.Digest, connBroker *connectionbroker.Broker) (RootCA, error) {
	// This TLS Config is intentionally using InsecureSkipVerify. We use the
	// digest instead to check the integrity of the CA certificate.
	insecureCreds := credentials.NewTLS(&tls.Config{InsecureSkipVerify: true})
	conn, err := getGRPCConnection(insecureCreds, connBroker, false)
	if err != nil {
		return RootCA{}, err
	}

	client := api.NewCAClient(conn.ClientConn)
	ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
	defer cancel()
	defer func() {
		conn.Close(err == nil)
	}()
	response, err := client.GetRootCACertificate(ctx, &api.GetRootCACertificateRequest{})
	if err != nil {
		return RootCA{}, err
	}

	// If a bundle of certificates are provided, the digest covers the entire bundle and not just
	// one of the certificates in the bundle.  Otherwise, a node can be MITMed while joining if
	// the MITM CA provides a single certificate which matches the digest, and providing arbitrary
	// other non-verified root certs that the manager certificate actually chains up to.
	if d != "" {
		verifier := d.Verifier()
		if err != nil {
			return RootCA{}, errors.Wrap(err, "unexpected error getting digest verifier")
		}

		io.Copy(verifier, bytes.NewReader(response.Certificate))

		if !verifier.Verified() {
			return RootCA{}, errors.Errorf("remote CA does not match fingerprint. Expected: %s", d.Hex())
		}
	}

	// NewRootCA will validate that the certificates are otherwise valid and create a RootCA object.
	// Since there is no key, the certificate expiry does not matter and will not be used.
	return NewRootCA(response.Certificate, nil, nil, DefaultNodeCertExpiration, nil)
}

// CreateRootCA creates a Certificate authority for a new Swarm Cluster, potentially
// overwriting any existing CAs.
func CreateRootCA(rootCN string) (RootCA, error) {
	// Create a simple CSR for the CA using the default CA validator and policy
	req := cfcsr.CertificateRequest{
		CN:         rootCN,
		KeyRequest: &cfcsr.BasicKeyRequest{A: RootKeyAlgo, S: RootKeySize},
		CA:         &cfcsr.CAConfig{Expiry: RootCAExpiration},
	}

	// Generate the CA and get the certificate and private key
	cert, _, key, err := initca.New(&req)
	if err != nil {
		return RootCA{}, err
	}

	rootCA, err := NewRootCA(cert, cert, key, DefaultNodeCertExpiration, nil)
	if err != nil {
		return RootCA{}, err
	}

	return rootCA, nil
}

// GetRemoteSignedCertificate submits a CSR to a remote CA server address,
// and that is part of a CA identified by a specific certificate pool.
func GetRemoteSignedCertificate(ctx context.Context, csr []byte, rootCAPool *x509.CertPool, config CertificateRequestConfig) ([]byte, error) {
	if rootCAPool == nil {
		return nil, errors.New("valid root CA pool required")
	}
	creds := config.Credentials

	if creds == nil {
		// This is our only non-MTLS request, and it happens when we are boostraping our TLS certs
		// We're using CARole as server name, so an external CA doesn't also have to have ManagerRole in the cert SANs
		creds = credentials.NewTLS(&tls.Config{ServerName: CARole, RootCAs: rootCAPool})
	}

	conn, err := getGRPCConnection(creds, config.ConnBroker, config.ForceRemote)
	if err != nil {
		return nil, err
	}

	// Create a CAClient to retrieve a new Certificate
	caClient := api.NewNodeCAClient(conn.ClientConn)

	issueCtx, issueCancel := context.WithTimeout(ctx, 5*time.Second)
	defer issueCancel()

	// Send the Request and retrieve the request token
	issueRequest := &api.IssueNodeCertificateRequest{CSR: csr, Token: config.Token, Availability: config.Availability}
	issueResponse, err := caClient.IssueNodeCertificate(issueCtx, issueRequest)
	if err != nil {
		conn.Close(false)
		return nil, err
	}

	statusRequest := &api.NodeCertificateStatusRequest{NodeID: issueResponse.NodeID}
	expBackoff := events.NewExponentialBackoff(events.ExponentialBackoffConfig{
		Base:   time.Second,
		Factor: time.Second,
		Max:    30 * time.Second,
	})

	// Exponential backoff with Max of 30 seconds to wait for a new retry
	for {
		timeout := 5 * time.Second
		if config.NodeCertificateStatusRequestTimeout > 0 {
			timeout = config.NodeCertificateStatusRequestTimeout
		}
		// Send the Request and retrieve the certificate
		stateCtx, cancel := context.WithTimeout(ctx, timeout)
		defer cancel()
		statusResponse, err := caClient.NodeCertificateStatus(stateCtx, statusRequest)
		s, _ := status.FromError(err)
		switch {
		case err != nil && s.Code() != codes.DeadlineExceeded:
			conn.Close(false)
			// Because IssueNodeCertificate succeeded, if this call failed likely it is due to an issue with this
			// particular connection, so we need to get another.  We should try a remote connection - the local node
			// may be a manager that was demoted, so the local connection (which is preferred) may not work.
			config.ForceRemote = true
			conn, err = getGRPCConnection(creds, config.ConnBroker, config.ForceRemote)
			if err != nil {
				return nil, err
			}
			caClient = api.NewNodeCAClient(conn.ClientConn)

		// If there was no deadline exceeded error, and the certificate was issued, return
		case err == nil && (statusResponse.Status.State == api.IssuanceStateIssued || statusResponse.Status.State == api.IssuanceStateRotate):
			if statusResponse.Certificate == nil {
				conn.Close(false)
				return nil, errors.New("no certificate in CertificateStatus response")
			}

			// The certificate in the response must match the CSR
			// we submitted. If we are getting a response for a
			// certificate that was previously issued, we need to
			// retry until the certificate gets updated per our
			// current request.
			if bytes.Equal(statusResponse.Certificate.CSR, csr) {
				conn.Close(true)
				return statusResponse.Certificate.Certificate, nil
			}
		}

		// If NodeCertificateStatus timed out, we're still pending, the issuance failed, or
		// the state is unknown let's continue trying after an exponential backoff
		expBackoff.Failure(nil, nil)
		select {
		case <-ctx.Done():
			conn.Close(true)
			return nil, err
		case <-time.After(expBackoff.Proceed(nil)):
		}
	}
}

// readCertValidity returns the certificate issue and expiration time
func readCertValidity(kr KeyReader) (time.Time, time.Time, error) {
	var zeroTime time.Time
	// Read the Cert
	cert, _, err := kr.Read()
	if err != nil {
		return zeroTime, zeroTime, err
	}

	// Create an x509 certificate out of the contents on disk
	certBlock, _ := pem.Decode(cert)
	if certBlock == nil {
		return zeroTime, zeroTime, errors.New("failed to decode certificate block")
	}
	X509Cert, err := x509.ParseCertificate(certBlock.Bytes)
	if err != nil {
		return zeroTime, zeroTime, err
	}

	return X509Cert.NotBefore, X509Cert.NotAfter, nil

}

// SaveRootCA saves a RootCA object to disk
func SaveRootCA(rootCA RootCA, paths CertPaths) error {
	// Make sure the necessary dirs exist and they are writable
	err := os.MkdirAll(filepath.Dir(paths.Cert), 0755)
	if err != nil {
		return err
	}

	// If the root certificate got returned successfully, save the rootCA to disk.
	return ioutils.AtomicWriteFile(paths.Cert, rootCA.Certs, 0644)
}

// GenerateNewCSR returns a newly generated key and CSR signed with said key
func GenerateNewCSR() ([]byte, []byte, error) {
	req := &cfcsr.CertificateRequest{
		KeyRequest: cfcsr.NewBasicKeyRequest(),
	}

	csr, key, err := cfcsr.ParseRequest(req)
	if err != nil {
		return nil, nil, err
	}

	key, err = pkcs8.ConvertECPrivateKeyPEM(key)
	return csr, key, err
}

// NormalizePEMs takes a bundle of PEM-encoded certificates in a certificate bundle,
// decodes them, removes headers, and re-encodes them to make sure that they have
// consistent whitespace.  Note that this is intended to normalize x509 certificates
// in PEM format, hence the stripping out of headers.
func NormalizePEMs(certs []byte) []byte {
	var (
		results  []byte
		pemBlock *pem.Block
	)
	for {
		pemBlock, certs = pem.Decode(bytes.TrimSpace(certs))
		if pemBlock == nil {
			return results
		}
		pemBlock.Headers = nil
		results = append(results, pem.EncodeToMemory(pemBlock)...)
	}
}
