func (b *backend) matchNonCAPolicy(clientCert *x509.Certificate, trustedNonCAs []*ParsedCert) *ParsedCert {
	for _, trustedNonCA := range trustedNonCAs {
		tCert := trustedNonCA.Certificates[0]
		if tCert.SerialNumber.Cmp(clientCert.SerialNumber) == 0 && bytes.Equal(tCert.AuthorityKeyId, clientCert.AuthorityKeyId) {
			return trustedNonCA
		}
	}
	return nil
}
matchNonCAPolicy is used to match the client cert with the registered non-CA
policies to establish client identity.
package cert
import (
	"bytes"
	"crypto/tls"
	"crypto/x509"
	"encoding/base64"
	"encoding/pem"
	"errors"
	"fmt"
	"strings"
	"github.com/hashicorp/vault/helper/certutil"
	"github.com/hashicorp/vault/helper/policyutil"
	"github.com/hashicorp/vault/logical"
	"github.com/hashicorp/vault/logical/framework"
)
type ParsedCert struct {
	Entry        *CertEntry
	Certificates []*x509.Certificate
}
func pathLogin(b *backend) *framework.Path {
	return &framework.Path{
		Pattern: "login",
		Fields:  map[string]*framework.FieldSchema{},
		Callbacks: map[logical.Operation]framework.OperationFunc{
			logical.UpdateOperation: b.pathLogin,
		},
	}
}
func (b *backend) pathLogin(
	req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
	var matched *ParsedCert
	if verifyResp, resp, err := b.verifyCredentials(req); err != nil {
		return nil, err
	} else if resp != nil {
		return resp, nil
	} else {
		matched = verifyResp
	}
	if matched == nil {
		return nil, nil
	}
	ttl := matched.Entry.TTL
	if ttl == 0 {
		ttl = b.System().DefaultLeaseTTL()
	}
	clientCerts := req.Connection.ConnState.PeerCertificates
	if len(clientCerts) == 0 {
		return logical.ErrorResponse("no client certificate found"), nil
	}
	skid := base64.StdEncoding.EncodeToString(clientCerts[0].SubjectKeyId)
	akid := base64.StdEncoding.EncodeToString(clientCerts[0].AuthorityKeyId)
	resp := &logical.Response{
		Auth: &logical.Auth{
			InternalData: map[string]interface{}{
				"subject_key_id":   skid,
				"authority_key_id": akid,
			},
			Policies:    matched.Entry.Policies,
			DisplayName: matched.Entry.DisplayName,
			Metadata: map[string]string{
				"cert_name":        matched.Entry.Name,
				"common_name":      clientCerts[0].Subject.CommonName,
				"subject_key_id":   certutil.GetHexFormatted(clientCerts[0].SubjectKeyId, ":"),
				"authority_key_id": certutil.GetHexFormatted(clientCerts[0].AuthorityKeyId, ":"),
			},
			LeaseOptions: logical.LeaseOptions{
				Renewable: true,
				TTL:       ttl,
			},
		},
	}
	return resp, nil
}
func (b *backend) pathLoginRenew(
	req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
	config, err := b.Config(req.Storage)
	if err != nil {
		return nil, err
	}
	if !config.DisableBinding {
		var matched *ParsedCert
		if verifyResp, resp, err := b.verifyCredentials(req); err != nil {
			return nil, err
		} else if resp != nil {
			return resp, nil
		} else {
			matched = verifyResp
		}
		if matched == nil {
			return nil, nil
		}
		clientCerts := req.Connection.ConnState.PeerCertificates
		if len(clientCerts) == 0 {
			return nil, fmt.Errorf("no client certificate found")
		}
		skid := base64.StdEncoding.EncodeToString(clientCerts[0].SubjectKeyId)
		akid := base64.StdEncoding.EncodeToString(clientCerts[0].AuthorityKeyId)
		if req.Auth.InternalData["subject_key_id"] != skid && req.Auth.InternalData["authority_key_id"] != akid {
			return nil, fmt.Errorf("client identity during renewal not matching client identity used during login")
		}
	}
	cert, err := b.Cert(req.Storage, req.Auth.Metadata["cert_name"])
	if err != nil {
		return nil, err
	}
	if cert == nil {
		return nil, nil
	}
	if !policyutil.EquivalentPolicies(cert.Policies, req.Auth.Policies) {
		return nil, fmt.Errorf("policies have changed, not renewing")
	}
	return framework.LeaseExtend(cert.TTL, 0, b.System())(req, d)
}
func (b *backend) verifyCredentials(req *logical.Request) (*ParsedCert, *logical.Response, error) {
	if req.Connection == nil || req.Connection.ConnState == nil {
		return nil, logical.ErrorResponse("tls connection required"), nil
	}
	connState := req.Connection.ConnState
	if connState.PeerCertificates == nil || len(connState.PeerCertificates) == 0 {
		return nil, logical.ErrorResponse("client certificate must be supplied"), nil
	}
	roots, trusted, trustedNonCAs := b.loadTrustedCerts(req.Storage)
	if len(trustedNonCAs) != 0 {
		policy := b.matchNonCAPolicy(connState.PeerCertificates[0], trustedNonCAs)
		if policy != nil && !b.checkForChainInCRLs(policy.Certificates) {
			return policy, nil, nil
		}
	}
	trustedChains, err := validateConnState(roots, connState)
	if err != nil {
		return nil, nil, err
	}
	if len(trustedChains) == 0 {
		return nil, logical.ErrorResponse("invalid certificate or no client certificate supplied"), nil
	}
	validChain := b.checkForValidChain(trustedChains)
	if !validChain {
		return nil, logical.ErrorResponse(
			"no chain containing non-revoked certificates could be found for this login certificate",
		), nil
	}
	return b.matchPolicy(trustedChains, trusted), nil, nil
}