mirror of
https://github.com/docker/docs.git
synced 2026-04-05 10:48:55 +07:00
Split out parsing the client TLS in notary-server.
Signed-off-by: Ying Li <ying.li@docker.com>
This commit is contained in:
@@ -70,6 +70,30 @@ func serverTLS(configuration *viper.Viper) (*tls.Config, error) {
|
||||
return tlsConfig, nil
|
||||
}
|
||||
|
||||
// sets up TLS for the GRPC connection to notary-signer
|
||||
func grpcTLS(configuration *viper.Viper) (*tls.Config, error) {
|
||||
rootCA := configuration.GetString("trust_service.tls_ca_file")
|
||||
serverName := configuration.GetString("trust_service.hostname")
|
||||
clientCert := configuration.GetString("trust_service.tls_client_cert")
|
||||
clientKey := configuration.GetString("trust_service.tls_client_key")
|
||||
|
||||
if (clientCert == "" && clientKey != "") || (clientCert != "" && clientKey == "") {
|
||||
return nil, fmt.Errorf("Partial TLS configuration found. Either include both a client cert and client key file in the configuration, or include neither.")
|
||||
}
|
||||
|
||||
tlsConfig, err := utils.ConfigureClientTLS(&utils.ClientTLSOpts{
|
||||
RootCAFile: rootCA,
|
||||
ServerName: serverName,
|
||||
ClientCertFile: clientCert,
|
||||
ClientKeyFile: clientKey,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"Unable to configure TLS to the trust service: %s", err.Error())
|
||||
}
|
||||
return tlsConfig, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Usage = usage
|
||||
flag.Parse()
|
||||
@@ -135,10 +159,14 @@ func main() {
|
||||
var trust signed.CryptoService
|
||||
if mainViper.GetString("trust_service.type") == "remote" {
|
||||
logrus.Info("Using remote signing service")
|
||||
clientTLS, err := grpcTLS(mainViper)
|
||||
if err != nil {
|
||||
logrus.Fatal(err.Error())
|
||||
}
|
||||
notarySigner := signer.NewNotarySigner(
|
||||
mainViper.GetString("trust_service.hostname"),
|
||||
mainViper.GetString("trust_service.port"),
|
||||
mainViper.GetString("trust_service.tls_ca_file"),
|
||||
clientTLS,
|
||||
)
|
||||
trust = notarySigner
|
||||
minute := 1 * time.Minute
|
||||
|
||||
@@ -32,6 +32,7 @@ func TestServerTLSMissingCertAndKey(t *testing.T) {
|
||||
assert.Nil(t, tlsConfig)
|
||||
}
|
||||
|
||||
// Cert and Key either both have to be empty or both have to be provided.
|
||||
func TestServerTLSMissingCertAndOrKey(t *testing.T) {
|
||||
configs := []string{
|
||||
fmt.Sprintf(`{"tls_cert_file": "%s"}`, Cert),
|
||||
@@ -63,7 +64,7 @@ func TestServerTLSSuccess(t *testing.T) {
|
||||
assert.Equal(t, []tls.Certificate{keypair}, tlsConfig.Certificates)
|
||||
}
|
||||
|
||||
// The rest of the functionality of singerTLS depends upon
|
||||
// The rest of the functionality of serverTLS depends upon
|
||||
// utils.ConfigureServerTLS, so this test just asserts that if it fails,
|
||||
// the error is propogated.
|
||||
func TestServerTLSFailure(t *testing.T) {
|
||||
@@ -75,3 +76,69 @@ func TestServerTLSFailure(t *testing.T) {
|
||||
assert.Nil(t, tlsConfig)
|
||||
assert.True(t, strings.Contains(err.Error(), "Unable to set up TLS"))
|
||||
}
|
||||
|
||||
// Client cert and Key either both have to be empty or both have to be
|
||||
// provided.
|
||||
func TestGrpcTLSMissingCertOrKey(t *testing.T) {
|
||||
configs := []string{
|
||||
fmt.Sprintf(`"tls_client_cert": "%s"`, Cert),
|
||||
fmt.Sprintf(`"tls_client_key": "%s"`, Key),
|
||||
}
|
||||
for _, trustConfig := range configs {
|
||||
jsonConfig := fmt.Sprintf(
|
||||
`{"trust_service": {"hostname": "notary-signer", %s}}`,
|
||||
trustConfig)
|
||||
config := configure([]byte(jsonConfig))
|
||||
tlsConfig, err := grpcTLS(config)
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, tlsConfig)
|
||||
assert.True(t,
|
||||
strings.Contains(err.Error(), "Partial TLS configuration found."))
|
||||
}
|
||||
}
|
||||
|
||||
// If no TLS configuration is provided for the host server, a tls config with
|
||||
// the provided serverName is still returned.
|
||||
func TestGrpcTLSNoConfig(t *testing.T) {
|
||||
tlsConfig, err := grpcTLS(
|
||||
configure([]byte(`{"trust_service": {"hostname": "notary-signer"}}`)))
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "notary-signer", tlsConfig.ServerName)
|
||||
assert.Nil(t, tlsConfig.RootCAs)
|
||||
assert.Nil(t, tlsConfig.Certificates)
|
||||
}
|
||||
|
||||
// The rest of the functionality of grpcTLS depends upon
|
||||
// utils.ConfigureClientTLS, so this test just asserts that if successful,
|
||||
// the correct tls.Config is returned based on all the configuration parameters
|
||||
func TestGrpcTLSSuccess(t *testing.T) {
|
||||
keypair, err := tls.LoadX509KeyPair(Cert, Key)
|
||||
assert.NoError(t, err, "Unable to load cert and key for testing")
|
||||
|
||||
config := fmt.Sprintf(
|
||||
`{"trust_service": {
|
||||
"hostname": "notary-server",
|
||||
"tls_client_cert": "%s",
|
||||
"tls_client_key": "%s"}}`,
|
||||
Cert, Key)
|
||||
tlsConfig, err := grpcTLS(configure([]byte(config)))
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, []tls.Certificate{keypair}, tlsConfig.Certificates)
|
||||
}
|
||||
|
||||
// The rest of the functionality of grpcTLS depends upon
|
||||
// utils.ConfigureServerTLS, so this test just asserts that if it fails,
|
||||
// the error is propogated.
|
||||
func TestGrpcTLSFailure(t *testing.T) {
|
||||
config := fmt.Sprintf(
|
||||
`{"trust_service": {
|
||||
"hostname": "notary-server",
|
||||
"tls_client_cert": "no-exist",
|
||||
"tls_client_key": "%s"}}`,
|
||||
Key)
|
||||
tlsConfig, err := grpcTLS(configure([]byte(config)))
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, tlsConfig)
|
||||
assert.True(t, strings.Contains(err.Error(),
|
||||
"Unable to configure TLS to the trust service"))
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ func TestSignerTLSMissingCertAndOrKey(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// The rest of the functionality of singerTLS depends upon
|
||||
// The rest of the functionality of signerTLS depends upon
|
||||
// utils.ConfigureServerTLS, so this test just asserts that if successful,
|
||||
// the correct tls.Config is returned based on all the configuration parameters
|
||||
func TestSignerTLSSuccess(t *testing.T) {
|
||||
@@ -57,7 +57,7 @@ func TestSignerTLSSuccess(t *testing.T) {
|
||||
assert.NotNil(t, tlsConfig.ClientCAs)
|
||||
}
|
||||
|
||||
// The rest of the functionality of singerTLS depends upon
|
||||
// The rest of the functionality of signerTLS depends upon
|
||||
// utils.ConfigureServerTLS, so this test just asserts that if it fails,
|
||||
// the error is propogated.
|
||||
func TestSignerTLSFailure(t *testing.T) {
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
package signer
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
pb "github.com/docker/notary/proto"
|
||||
"github.com/docker/notary/tuf/data"
|
||||
"github.com/docker/notary/utils"
|
||||
"github.com/endophage/gotuf/data"
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
@@ -28,16 +28,9 @@ type NotarySigner struct {
|
||||
}
|
||||
|
||||
// NewNotarySigner is a convinience method that returns NotarySigner
|
||||
func NewNotarySigner(hostname string, port string, tlscafile string) *NotarySigner {
|
||||
func NewNotarySigner(hostname string, port string, tlsConfig *tls.Config) *NotarySigner {
|
||||
var opts []grpc.DialOption
|
||||
netAddr := net.JoinHostPort(hostname, port)
|
||||
tlsConfig, err := utils.ConfigureClientTLS(&utils.ClientTLSOpts{
|
||||
RootCAFile: tlscafile,
|
||||
ServerName: hostname,
|
||||
})
|
||||
if err != nil {
|
||||
logrus.Fatal("Unable to set up TLS: ", err)
|
||||
}
|
||||
creds := credentials.NewTLS(tlsConfig)
|
||||
opts = append(opts, grpc.WithTransportCredentials(creds))
|
||||
conn, err := grpc.Dial(netAddr, opts...)
|
||||
|
||||
Reference in New Issue
Block a user