Split out parsing the client TLS in notary-server.

Signed-off-by: Ying Li <ying.li@docker.com>
This commit is contained in:
Ying Li
2015-10-19 18:39:37 -07:00
parent 04a78e720f
commit 34aecae033
4 changed files with 102 additions and 14 deletions

View File

@@ -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

View File

@@ -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"))
}

View File

@@ -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) {

View File

@@ -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...)