2019-09-05 16:11:21 +01:00
|
|
|
// Copyright (C) 2019 Storj Labs, Inc.
|
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
|
|
|
package certificateclient
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"time"
|
|
|
|
|
2019-09-10 17:24:41 +01:00
|
|
|
"github.com/zeebo/errs"
|
2019-09-05 16:11:21 +01:00
|
|
|
"gopkg.in/spacemonkeygo/monkit.v2"
|
|
|
|
|
|
|
|
"storj.io/storj/pkg/identity"
|
|
|
|
"storj.io/storj/pkg/pb"
|
|
|
|
"storj.io/storj/pkg/peertls/tlsopts"
|
2019-09-19 05:46:39 +01:00
|
|
|
"storj.io/storj/pkg/rpc"
|
2019-09-05 16:11:21 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
var mon = monkit.Package()
|
|
|
|
|
|
|
|
// Config is a config struct for use with a certificate signing service client.
|
|
|
|
type Config struct {
|
|
|
|
Address string `help:"address of the certificate signing rpc service"`
|
|
|
|
TLS tlsopts.Config
|
|
|
|
}
|
|
|
|
|
2019-09-19 05:46:39 +01:00
|
|
|
// Client implements rpc.CertificatesClient
|
2019-09-05 16:11:21 +01:00
|
|
|
type Client struct {
|
2019-09-19 05:46:39 +01:00
|
|
|
conn *rpc.Conn
|
|
|
|
client rpc.CertificatesClient
|
2019-09-05 16:11:21 +01:00
|
|
|
}
|
|
|
|
|
2019-09-19 05:46:39 +01:00
|
|
|
// New creates a new certificate signing rpc client.
|
|
|
|
func New(ctx context.Context, dialer rpc.Dialer, address string) (_ *Client, err error) {
|
2019-09-05 16:11:21 +01:00
|
|
|
defer mon.Task()(&ctx, address)(&err)
|
|
|
|
|
2019-09-19 05:46:39 +01:00
|
|
|
conn, err := dialer.DialAddressInsecure(ctx, address)
|
2019-09-05 16:11:21 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &Client{
|
|
|
|
conn: conn,
|
2019-09-19 05:46:39 +01:00
|
|
|
client: conn.CertificatesClient(),
|
2019-09-05 16:11:21 +01:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewClientFrom creates a new certificate signing gRPC client from an existing
|
|
|
|
// grpc cert signing client.
|
2019-09-19 05:46:39 +01:00
|
|
|
func NewClientFrom(client rpc.CertificatesClient) *Client {
|
2019-09-05 16:11:21 +01:00
|
|
|
return &Client{
|
|
|
|
client: client,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sign submits a certificate signing request given the config.
|
|
|
|
func (config Config) Sign(ctx context.Context, ident *identity.FullIdentity, authToken string) (_ [][]byte, err error) {
|
|
|
|
defer mon.Task()(&ctx)(&err)
|
|
|
|
|
2019-09-19 05:46:39 +01:00
|
|
|
tlsOptions, err := tlsopts.NewOptions(ident, config.TLS, nil)
|
2019-09-05 16:11:21 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2019-09-19 05:46:39 +01:00
|
|
|
client, err := New(ctx, rpc.NewDefaultDialer(tlsOptions), config.Address)
|
2019-09-05 16:11:21 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2019-09-19 05:46:39 +01:00
|
|
|
defer func() { err = errs.Combine(err, client.Close()) }()
|
2019-09-05 16:11:21 +01:00
|
|
|
|
|
|
|
return client.Sign(ctx, authToken)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sign claims an authorization using the token string and returns a signed
|
|
|
|
// copy of the client's CA certificate.
|
|
|
|
func (client *Client) Sign(ctx context.Context, tokenStr string) (_ [][]byte, err error) {
|
|
|
|
defer mon.Task()(&ctx)(&err)
|
|
|
|
|
|
|
|
res, err := client.client.Sign(ctx, &pb.SigningRequest{
|
|
|
|
AuthToken: tokenStr,
|
|
|
|
Timestamp: time.Now().Unix(),
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return res.Chain, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Close closes the client.
|
|
|
|
func (client *Client) Close() error {
|
|
|
|
if client.conn != nil {
|
|
|
|
return client.conn.Close()
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|