mirror of https://github.com/hashicorp/consul
234 lines
6.4 KiB
Go
234 lines
6.4 KiB
Go
package plugin
|
|
|
|
import (
|
|
"context"
|
|
"crypto/x509"
|
|
"encoding/json"
|
|
"time"
|
|
|
|
"github.com/gogo/protobuf/types"
|
|
"google.golang.org/grpc"
|
|
|
|
"github.com/hashicorp/consul/agent/connect/ca"
|
|
)
|
|
|
|
// providerPluginGRPCServer implements the CAServer interface for gRPC.
|
|
type providerPluginGRPCServer struct {
|
|
impl ca.Provider
|
|
}
|
|
|
|
func (p *providerPluginGRPCServer) Configure(_ context.Context, req *ConfigureRequest) (*Empty, error) {
|
|
var rawConfig map[string]interface{}
|
|
if err := json.Unmarshal(req.Config, &rawConfig); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &Empty{}, p.impl.Configure(req.ClusterId, req.IsRoot, rawConfig)
|
|
}
|
|
|
|
func (p *providerPluginGRPCServer) GenerateRoot(context.Context, *Empty) (*Empty, error) {
|
|
return &Empty{}, p.impl.GenerateRoot()
|
|
}
|
|
|
|
func (p *providerPluginGRPCServer) ActiveRoot(context.Context, *Empty) (*ActiveRootResponse, error) {
|
|
pem, err := p.impl.ActiveRoot()
|
|
return &ActiveRootResponse{CrtPem: pem}, err
|
|
}
|
|
|
|
func (p *providerPluginGRPCServer) GenerateIntermediateCSR(context.Context, *Empty) (*GenerateIntermediateCSRResponse, error) {
|
|
pem, err := p.impl.GenerateIntermediateCSR()
|
|
return &GenerateIntermediateCSRResponse{CsrPem: pem}, err
|
|
}
|
|
|
|
func (p *providerPluginGRPCServer) SetIntermediate(_ context.Context, req *SetIntermediateRequest) (*Empty, error) {
|
|
return &Empty{}, p.impl.SetIntermediate(req.IntermediatePem, req.RootPem)
|
|
}
|
|
|
|
func (p *providerPluginGRPCServer) ActiveIntermediate(context.Context, *Empty) (*ActiveIntermediateResponse, error) {
|
|
pem, err := p.impl.ActiveIntermediate()
|
|
return &ActiveIntermediateResponse{CrtPem: pem}, err
|
|
}
|
|
|
|
func (p *providerPluginGRPCServer) GenerateIntermediate(context.Context, *Empty) (*GenerateIntermediateResponse, error) {
|
|
pem, err := p.impl.GenerateIntermediate()
|
|
return &GenerateIntermediateResponse{CrtPem: pem}, err
|
|
}
|
|
|
|
func (p *providerPluginGRPCServer) Sign(_ context.Context, req *SignRequest) (*SignResponse, error) {
|
|
csr, err := x509.ParseCertificateRequest(req.Csr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
crtPEM, err := p.impl.Sign(csr)
|
|
return &SignResponse{CrtPem: crtPEM}, err
|
|
}
|
|
|
|
func (p *providerPluginGRPCServer) SignIntermediate(_ context.Context, req *SignIntermediateRequest) (*SignIntermediateResponse, error) {
|
|
csr, err := x509.ParseCertificateRequest(req.Csr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
crtPEM, err := p.impl.SignIntermediate(csr)
|
|
return &SignIntermediateResponse{CrtPem: crtPEM}, err
|
|
}
|
|
|
|
func (p *providerPluginGRPCServer) CrossSignCA(_ context.Context, req *CrossSignCARequest) (*CrossSignCAResponse, error) {
|
|
crt, err := x509.ParseCertificate(req.Crt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
crtPEM, err := p.impl.CrossSignCA(crt)
|
|
return &CrossSignCAResponse{CrtPem: crtPEM}, err
|
|
}
|
|
|
|
func (p *providerPluginGRPCServer) SupportsCrossSigning(context.Context, *Empty) (*SupportsCrossSigningResponse, error) {
|
|
s := p.impl.SupportsCrossSigning()
|
|
return &SupportsCrossSigningResponse{SupportsCrossSigning: s}, nil
|
|
}
|
|
|
|
func (p *providerPluginGRPCServer) MinLifetime(context.Context, *Empty) (*MinLifetimeResponse, error) {
|
|
return &MinLifetimeResponse{MinLifetime: types.DurationProto(p.impl.MinLifetime())}, nil
|
|
}
|
|
|
|
func (p *providerPluginGRPCServer) Cleanup(context.Context, *Empty) (*Empty, error) {
|
|
return &Empty{}, p.impl.Cleanup()
|
|
}
|
|
|
|
// providerPluginGRPCClient implements ca.Provider for acting as a client
|
|
// to a remote CA provider plugin over gRPC.
|
|
type providerPluginGRPCClient struct {
|
|
client CAClient
|
|
clientConn *grpc.ClientConn
|
|
doneCtx context.Context
|
|
}
|
|
|
|
func (p *providerPluginGRPCClient) Configure(
|
|
clusterId string,
|
|
isRoot bool,
|
|
rawConfig map[string]interface{}) error {
|
|
config, err := json.Marshal(rawConfig)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = p.client.Configure(p.doneCtx, &ConfigureRequest{
|
|
ClusterId: clusterId,
|
|
IsRoot: isRoot,
|
|
Config: config,
|
|
})
|
|
return p.err(err)
|
|
}
|
|
|
|
func (p *providerPluginGRPCClient) GenerateRoot() error {
|
|
_, err := p.client.GenerateRoot(p.doneCtx, &Empty{})
|
|
return p.err(err)
|
|
}
|
|
|
|
func (p *providerPluginGRPCClient) ActiveRoot() (string, error) {
|
|
resp, err := p.client.ActiveRoot(p.doneCtx, &Empty{})
|
|
if err != nil {
|
|
return "", p.err(err)
|
|
}
|
|
|
|
return resp.CrtPem, nil
|
|
}
|
|
|
|
func (p *providerPluginGRPCClient) GenerateIntermediateCSR() (string, error) {
|
|
resp, err := p.client.GenerateIntermediateCSR(p.doneCtx, &Empty{})
|
|
if err != nil {
|
|
return "", p.err(err)
|
|
}
|
|
|
|
return resp.CsrPem, nil
|
|
}
|
|
|
|
func (p *providerPluginGRPCClient) SetIntermediate(intermediatePEM, rootPEM string) error {
|
|
_, err := p.client.SetIntermediate(p.doneCtx, &SetIntermediateRequest{
|
|
IntermediatePem: intermediatePEM,
|
|
RootPem: rootPEM,
|
|
})
|
|
return p.err(err)
|
|
}
|
|
|
|
func (p *providerPluginGRPCClient) ActiveIntermediate() (string, error) {
|
|
resp, err := p.client.ActiveIntermediate(p.doneCtx, &Empty{})
|
|
if err != nil {
|
|
return "", p.err(err)
|
|
}
|
|
|
|
return resp.CrtPem, nil
|
|
}
|
|
|
|
func (p *providerPluginGRPCClient) GenerateIntermediate() (string, error) {
|
|
resp, err := p.client.GenerateIntermediate(p.doneCtx, &Empty{})
|
|
if err != nil {
|
|
return "", p.err(err)
|
|
}
|
|
|
|
return resp.CrtPem, nil
|
|
}
|
|
|
|
func (p *providerPluginGRPCClient) Sign(csr *x509.CertificateRequest) (string, error) {
|
|
resp, err := p.client.Sign(p.doneCtx, &SignRequest{
|
|
Csr: csr.Raw,
|
|
})
|
|
if err != nil {
|
|
return "", p.err(err)
|
|
}
|
|
|
|
return resp.CrtPem, nil
|
|
}
|
|
|
|
func (p *providerPluginGRPCClient) SignIntermediate(csr *x509.CertificateRequest) (string, error) {
|
|
resp, err := p.client.SignIntermediate(p.doneCtx, &SignIntermediateRequest{
|
|
Csr: csr.Raw,
|
|
})
|
|
if err != nil {
|
|
return "", p.err(err)
|
|
}
|
|
|
|
return resp.CrtPem, nil
|
|
}
|
|
|
|
func (p *providerPluginGRPCClient) CrossSignCA(crt *x509.Certificate) (string, error) {
|
|
resp, err := p.client.CrossSignCA(p.doneCtx, &CrossSignCARequest{
|
|
Crt: crt.Raw,
|
|
})
|
|
if err != nil {
|
|
return "", p.err(err)
|
|
}
|
|
|
|
return resp.CrtPem, nil
|
|
}
|
|
|
|
func (p *providerPluginGRPCClient) SupportsCrossSigning() bool {
|
|
resp, _ := p.client.SupportsCrossSigning(p.doneCtx, &Empty{})
|
|
return resp.SupportsCrossSigning
|
|
}
|
|
|
|
func (p *providerPluginGRPCClient) MinLifetime() time.Duration {
|
|
resp, _ := p.client.MinLifetime(p.doneCtx, &Empty{})
|
|
min, _ := types.DurationFromProto(resp.MinLifetime)
|
|
return min
|
|
}
|
|
|
|
func (p *providerPluginGRPCClient) Cleanup() error {
|
|
_, err := p.client.Cleanup(p.doneCtx, &Empty{})
|
|
return p.err(err)
|
|
}
|
|
|
|
func (p *providerPluginGRPCClient) err(err error) error {
|
|
if err := p.doneCtx.Err(); err != nil {
|
|
return err
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
// Verification
|
|
var _ CAServer = &providerPluginGRPCServer{}
|
|
var _ ca.Provider = &providerPluginGRPCClient{}
|